Merge "Show broken lock image when SSL errors are encountered in CaptivePortalLogin." into lmp-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 3b30bb0..725c27d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21319,6 +21319,9 @@
     method public void clear();
     method public boolean containsKey(java.lang.String);
     method public java.lang.Object get(java.lang.String);
+    method public boolean getBoolean(java.lang.String);
+    method public boolean getBoolean(java.lang.String, boolean);
+    method public boolean[] getBooleanArray(java.lang.String);
     method public double getDouble(java.lang.String);
     method public double getDouble(java.lang.String, double);
     method public double[] getDoubleArray(java.lang.String);
@@ -21334,6 +21337,8 @@
     method public boolean isEmpty();
     method public java.util.Set<java.lang.String> keySet();
     method public void putAll(android.os.PersistableBundle);
+    method public void putBoolean(java.lang.String, boolean);
+    method public void putBooleanArray(java.lang.String, boolean[]);
     method public void putDouble(java.lang.String, double);
     method public void putDoubleArray(java.lang.String, double[]);
     method public void putInt(java.lang.String, int);
@@ -21479,9 +21484,6 @@
     method public java.lang.Object clone();
     method public int describeContents();
     method public android.os.IBinder getBinder(java.lang.String);
-    method public boolean getBoolean(java.lang.String);
-    method public boolean getBoolean(java.lang.String, boolean);
-    method public boolean[] getBooleanArray(java.lang.String);
     method public android.os.Bundle getBundle(java.lang.String);
     method public byte getByte(java.lang.String);
     method public java.lang.Byte getByte(java.lang.String, byte);
@@ -21512,8 +21514,6 @@
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
-    method public void putBoolean(java.lang.String, boolean);
-    method public void putBooleanArray(java.lang.String, boolean[]);
     method public void putBundle(java.lang.String, android.os.Bundle);
     method public void putByte(java.lang.String, byte);
     method public void putByteArray(java.lang.String, byte[]);
@@ -28651,7 +28651,6 @@
     method public boolean isNetworkRoaming(int);
     method public void registerOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method public void unregisterOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
-    field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
 
   public static class SubscriptionManager.OnSubscriptionsChangedListener {
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 1ca14a6..397a7d1 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -2,15 +2,10 @@
 
 include $(CLEAR_VARS)
 
-# TODO: Trying to link libsigchain as a static library prevents
-# static linker from exporting necessary symbols. So as a workaround
-# we use sigchain.o
 LOCAL_SRC_FILES:= \
-	app_main.cpp \
-	sigchain_proxy.cpp
+	app_main.cpp
 
 LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
 
 LOCAL_SHARED_LIBRARIES := \
 	libdl \
@@ -20,6 +15,8 @@
 	libbinder \
 	libandroid_runtime
 
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
+
 LOCAL_MODULE:= app_process
 LOCAL_MULTILIB := both
 LOCAL_MODULE_STEM_32 := app_process32
@@ -36,10 +33,8 @@
 
 include $(CLEAR_VARS)
 
-# see comment above (~l5)
 LOCAL_SRC_FILES:= \
-	app_main.cpp \
-	sigchain_proxy.cpp
+	app_main.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
@@ -48,8 +43,10 @@
 	libbinder \
 	libandroid_runtime
 
+LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
+
 LOCAL_LDFLAGS := -ldl -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
-LOCAL_CPPFLAGS := -std=c++11 -Iart
+LOCAL_CPPFLAGS := -std=c++11
 
 LOCAL_MODULE := app_process__asan
 LOCAL_MODULE_TAGS := eng
diff --git a/cmds/uiautomator/Android.mk b/cmds/uiautomator/Android.mk
new file mode 100644
index 0000000..5391305
--- /dev/null
+++ b/cmds/uiautomator/Android.mk
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+# don't build uiautomator in unbundled env
+ifndef TARGET_BUILD_APPS
+include $(call all-subdir-makefiles)
+else
+ifneq ($(filter uiautomator,$(TARGET_BUILD_APPS)),)
+# used by the platform apps build.
+include $(call all-subdir-makefiles)
+endif
+endif
diff --git a/cmds/uiautomator/MODULE_LICENSE_APACHE2 b/cmds/uiautomator/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/uiautomator/MODULE_LICENSE_APACHE2
diff --git a/cmds/uiautomator/api/16.txt b/cmds/uiautomator/api/16.txt
new file mode 100644
index 0000000..f3b0eb7
--- /dev/null
+++ b/cmds/uiautomator/api/16.txt
@@ -0,0 +1,174 @@
+package com.android.uiautomator.core {
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward();
+    method public boolean flingForward();
+    method public boolean flingToBeginning(int);
+    method public boolean flingToEnd(int);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward();
+    method public boolean scrollBackward(int);
+    method public boolean scrollDescriptionIntoView(java.lang.String);
+    method public boolean scrollForward();
+    method public boolean scrollForward(int);
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector);
+    method public boolean scrollTextIntoView(java.lang.String);
+    method public boolean scrollToBeginning(int, int);
+    method public boolean scrollToBeginning(int);
+    method public boolean scrollToEnd(int, int);
+    method public boolean scrollToEnd(int);
+    method public void setAsHorizontalList();
+    method public void setAsVerticalList();
+    method public void setMaxSearchSwipes(int);
+    method public void setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/cmds/uiautomator/api/17.txt b/cmds/uiautomator/api/17.txt
new file mode 100644
index 0000000..a1d80c4
--- /dev/null
+++ b/cmds/uiautomator/api/17.txt
@@ -0,0 +1,192 @@
+package com.android.uiautomator.core {
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public deprecated java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayRotation();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public java.lang.String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
+    method public com.android.uiautomator.core.UiScrollable setAsVerticalList();
+    method public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
+    method public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.Class<T>);
+    method public com.android.uiautomator.core.UiSelector classNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method protected com.android.uiautomator.core.UiSelector cloneSelector();
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector longClickable(boolean);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector packageNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/cmds/uiautomator/api/current.txt b/cmds/uiautomator/api/current.txt
new file mode 100644
index 0000000..7eeecf5
--- /dev/null
+++ b/cmds/uiautomator/api/current.txt
@@ -0,0 +1,222 @@
+package com.android.uiautomator.core {
+
+  public final class Configurator {
+    method public long getActionAcknowledgmentTimeout();
+    method public static com.android.uiautomator.core.Configurator getInstance();
+    method public long getKeyInjectionDelay();
+    method public long getScrollAcknowledgmentTimeout();
+    method public long getWaitForIdleTimeout();
+    method public long getWaitForSelectorTimeout();
+    method public com.android.uiautomator.core.Configurator setActionAcknowledgmentTimeout(long);
+    method public com.android.uiautomator.core.Configurator setKeyInjectionDelay(long);
+    method public com.android.uiautomator.core.Configurator setScrollAcknowledgmentTimeout(long);
+    method public com.android.uiautomator.core.Configurator setWaitForIdleTimeout(long);
+    method public com.android.uiautomator.core.Configurator setWaitForSelectorTimeout(long);
+  }
+
+  public class UiCollection extends com.android.uiautomator.core.UiObject {
+    ctor public UiCollection(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByInstance(com.android.uiautomator.core.UiSelector, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount(com.android.uiautomator.core.UiSelector);
+  }
+
+  public class UiDevice {
+    method public void clearLastTraversedText();
+    method public boolean click(int, int);
+    method public boolean drag(int, int, int, int, int);
+    method public void dumpWindowHierarchy(java.lang.String);
+    method public void freezeRotation() throws android.os.RemoteException;
+    method public deprecated java.lang.String getCurrentActivityName();
+    method public java.lang.String getCurrentPackageName();
+    method public int getDisplayHeight();
+    method public int getDisplayRotation();
+    method public android.graphics.Point getDisplaySizeDp();
+    method public int getDisplayWidth();
+    method public static com.android.uiautomator.core.UiDevice getInstance();
+    method public java.lang.String getLastTraversedText();
+    method public java.lang.String getProductName();
+    method public boolean hasAnyWatcherTriggered();
+    method public boolean hasWatcherTriggered(java.lang.String);
+    method public boolean isNaturalOrientation();
+    method public boolean isScreenOn() throws android.os.RemoteException;
+    method public boolean openNotification();
+    method public boolean openQuickSettings();
+    method public boolean pressBack();
+    method public boolean pressDPadCenter();
+    method public boolean pressDPadDown();
+    method public boolean pressDPadLeft();
+    method public boolean pressDPadRight();
+    method public boolean pressDPadUp();
+    method public boolean pressDelete();
+    method public boolean pressEnter();
+    method public boolean pressHome();
+    method public boolean pressKeyCode(int);
+    method public boolean pressKeyCode(int, int);
+    method public boolean pressMenu();
+    method public boolean pressRecentApps() throws android.os.RemoteException;
+    method public boolean pressSearch();
+    method public void registerWatcher(java.lang.String, com.android.uiautomator.core.UiWatcher);
+    method public void removeWatcher(java.lang.String);
+    method public void resetWatcherTriggers();
+    method public void runWatchers();
+    method public void setCompressedLayoutHeirarchy(boolean);
+    method public void setOrientationLeft() throws android.os.RemoteException;
+    method public void setOrientationNatural() throws android.os.RemoteException;
+    method public void setOrientationRight() throws android.os.RemoteException;
+    method public void sleep() throws android.os.RemoteException;
+    method public boolean swipe(int, int, int, int, int);
+    method public boolean swipe(android.graphics.Point[], int);
+    method public boolean takeScreenshot(java.io.File);
+    method public boolean takeScreenshot(java.io.File, float, int);
+    method public void unfreezeRotation() throws android.os.RemoteException;
+    method public void waitForIdle();
+    method public void waitForIdle(long);
+    method public boolean waitForWindowUpdate(java.lang.String, long);
+    method public void wakeUp() throws android.os.RemoteException;
+  }
+
+  public class UiObject {
+    ctor public UiObject(com.android.uiautomator.core.UiSelector);
+    method public void clearTextField() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean click() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickAndWaitForNewWindow(long) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean clickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean dragTo(com.android.uiautomator.core.UiObject, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean dragTo(int, int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean exists();
+    method protected android.view.accessibility.AccessibilityNodeInfo findAccessibilityNodeInfo(long);
+    method public android.graphics.Rect getBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChild(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getChildCount() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getClassName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getContentDescription() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getFromParent(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public java.lang.String getPackageName() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public final com.android.uiautomator.core.UiSelector getSelector();
+    method public java.lang.String getText() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public android.graphics.Rect getVisibleBounds() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isCheckable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isChecked() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isEnabled() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocusable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isFocused() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isLongClickable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isScrollable() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean isSelected() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClick() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickBottomRight() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean longClickTopLeft() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean performMultiPointerGesture(android.view.MotionEvent.PointerCoords...);
+    method public boolean performTwoPointerGesture(android.graphics.Point, android.graphics.Point, android.graphics.Point, android.graphics.Point, int);
+    method public boolean pinchIn(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean pinchOut(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean setText(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeDown(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeLeft(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeRight(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean swipeUp(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean waitForExists(long);
+    method public boolean waitUntilGone(long);
+    field protected static final int FINGER_TOUCH_HALF_WIDTH = 20; // 0x14
+    field protected static final int SWIPE_MARGIN_LIMIT = 5; // 0x5
+    field protected static final deprecated long WAIT_FOR_EVENT_TMEOUT = 3000L; // 0xbb8L
+    field protected static final long WAIT_FOR_SELECTOR_POLL = 1000L; // 0x3e8L
+    field protected static final deprecated long WAIT_FOR_SELECTOR_TIMEOUT = 10000L; // 0x2710L
+    field protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500L; // 0x157cL
+  }
+
+  public class UiObjectNotFoundException extends java.lang.Exception {
+    ctor public UiObjectNotFoundException(java.lang.String);
+    ctor public UiObjectNotFoundException(java.lang.String, java.lang.Throwable);
+    ctor public UiObjectNotFoundException(java.lang.Throwable);
+  }
+
+  public class UiScrollable extends com.android.uiautomator.core.UiCollection {
+    ctor public UiScrollable(com.android.uiautomator.core.UiSelector);
+    method protected boolean exists(com.android.uiautomator.core.UiSelector);
+    method public boolean flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean flingToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByDescription(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiObject getChildByText(com.android.uiautomator.core.UiSelector, java.lang.String, boolean) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public int getMaxSearchSwipes();
+    method public double getSwipeDeadZonePercentage();
+    method public boolean scrollBackward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollBackward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollDescriptionIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward() throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollForward(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollIntoView(com.android.uiautomator.core.UiSelector) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollTextIntoView(java.lang.String) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToBeginning(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int, int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public boolean scrollToEnd(int) throws com.android.uiautomator.core.UiObjectNotFoundException;
+    method public com.android.uiautomator.core.UiScrollable setAsHorizontalList();
+    method public com.android.uiautomator.core.UiScrollable setAsVerticalList();
+    method public com.android.uiautomator.core.UiScrollable setMaxSearchSwipes(int);
+    method public com.android.uiautomator.core.UiScrollable setSwipeDeadZonePercentage(double);
+  }
+
+  public class UiSelector {
+    ctor public UiSelector();
+    method public com.android.uiautomator.core.UiSelector checkable(boolean);
+    method public com.android.uiautomator.core.UiSelector checked(boolean);
+    method public com.android.uiautomator.core.UiSelector childSelector(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector className(java.lang.Class<T>);
+    method public com.android.uiautomator.core.UiSelector classNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector clickable(boolean);
+    method protected com.android.uiautomator.core.UiSelector cloneSelector();
+    method public com.android.uiautomator.core.UiSelector description(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector descriptionStartsWith(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector enabled(boolean);
+    method public com.android.uiautomator.core.UiSelector focusable(boolean);
+    method public com.android.uiautomator.core.UiSelector focused(boolean);
+    method public com.android.uiautomator.core.UiSelector fromParent(com.android.uiautomator.core.UiSelector);
+    method public com.android.uiautomator.core.UiSelector index(int);
+    method public com.android.uiautomator.core.UiSelector instance(int);
+    method public com.android.uiautomator.core.UiSelector longClickable(boolean);
+    method public com.android.uiautomator.core.UiSelector packageName(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector packageNameMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector resourceId(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector resourceIdMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector scrollable(boolean);
+    method public com.android.uiautomator.core.UiSelector selected(boolean);
+    method public com.android.uiautomator.core.UiSelector text(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textContains(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textMatches(java.lang.String);
+    method public com.android.uiautomator.core.UiSelector textStartsWith(java.lang.String);
+  }
+
+  public abstract interface UiWatcher {
+    method public abstract boolean checkForCondition();
+  }
+
+}
+
+package com.android.uiautomator.testrunner {
+
+  public abstract interface IAutomationSupport {
+    method public abstract void sendStatus(int, android.os.Bundle);
+  }
+
+  public class UiAutomatorTestCase extends junit.framework.TestCase {
+    ctor public UiAutomatorTestCase();
+    method public com.android.uiautomator.testrunner.IAutomationSupport getAutomationSupport();
+    method public android.os.Bundle getParams();
+    method public com.android.uiautomator.core.UiDevice getUiDevice();
+    method public void sleep(long);
+  }
+
+}
+
diff --git a/cmds/uiautomator/api/removed.txt b/cmds/uiautomator/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/uiautomator/api/removed.txt
diff --git a/cmds/uiautomator/cmds/Android.mk b/cmds/uiautomator/cmds/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/cmds/uiautomator/cmds/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/cmds/uiautomator/cmds/uiautomator/Android.mk b/cmds/uiautomator/cmds/uiautomator/Android.mk
new file mode 100644
index 0000000..5c91b52
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/Android.mk
@@ -0,0 +1,33 @@
+#
+# 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_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := uiautomator.core
+LOCAL_MODULE := uiautomator
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := uiautomator
+LOCAL_SRC_FILES := uiautomator
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_PREBUILT)
diff --git a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
new file mode 100644
index 0000000..c35f7fc
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.uiautomator;
+
+import android.app.UiAutomation;
+import android.graphics.Point;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Environment;
+import android.view.Display;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.core.AccessibilityNodeInfoDumper;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+
+import java.io.File;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Implementation of the dump subcommand
+ *
+ * This creates an XML dump of current UI hierarchy
+ */
+public class DumpCommand extends Command {
+
+    private static final File DEFAULT_DUMP_FILE = new File(
+            Environment.getLegacyExternalStorageDirectory(), "window_dump.xml");
+
+    public DumpCommand() {
+        super("dump");
+    }
+
+    @Override
+    public String shortHelp() {
+        return "creates an XML dump of current UI hierarchy";
+    }
+
+    @Override
+    public String detailedOptions() {
+        return "    dump [--verbose][file]\n"
+            + "      [--compressed]: dumps compressed layout information.\n"
+            + "      [file]: the location where the dumped XML should be stored, default is\n      "
+            + DEFAULT_DUMP_FILE.getAbsolutePath() + "\n";
+    }
+
+    @Override
+    public void run(String[] args) {
+        File dumpFile = DEFAULT_DUMP_FILE;
+        boolean verboseMode = true;
+
+        for (String arg : args) {
+            if (arg.equals("--compressed"))
+                verboseMode = false;
+            else if (!arg.startsWith("-")) {
+                dumpFile = new File(arg);
+            }
+        }
+
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+        if (verboseMode) {
+            // default
+            automationWrapper.setCompressedLayoutHierarchy(false);
+        } else {
+            automationWrapper.setCompressedLayoutHierarchy(true);
+        }
+
+        // It appears that the bridge needs time to be ready. Making calls to the
+        // bridge immediately after connecting seems to cause exceptions. So let's also
+        // do a wait for idle in case the app is busy.
+        try {
+            UiAutomation uiAutomation = automationWrapper.getUiAutomation();
+            uiAutomation.waitForIdle(1000, 1000 * 10);
+            AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow();
+            if (info == null) {
+                System.err.println("ERROR: null root node returned by UiTestAutomationBridge.");
+                return;
+            }
+
+            Display display =
+                    DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+            int rotation = display.getRotation();
+            Point size = new Point();
+            display.getSize(size);
+            AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y);
+        } catch (TimeoutException re) {
+            System.err.println("ERROR: could not get idle state.");
+            return;
+        } finally {
+            automationWrapper.disconnect();
+        }
+        System.out.println(
+                String.format("UI hierchary dumped to: %s", dumpFile.getAbsolutePath()));
+    }
+}
diff --git a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java
new file mode 100644
index 0000000..ce55f18
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/EventsCommand.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.uiautomator;
+
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Implementation of the events subcommand
+ *
+ * Prints out accessibility events until process is stopped.
+ */
+public class EventsCommand extends Command {
+
+    private Object mQuitLock = new Object();
+
+    public EventsCommand() {
+        super("events");
+    }
+
+    @Override
+    public String shortHelp() {
+        return "prints out accessibility events until terminated";
+    }
+
+    @Override
+    public String detailedOptions() {
+        return null;
+    }
+
+    @Override
+    public void run(String[] args) {
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+        automationWrapper.getUiAutomation().setOnAccessibilityEventListener(
+                new OnAccessibilityEventListener() {
+            @Override
+            public void onAccessibilityEvent(AccessibilityEvent event) {
+                SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+                System.out.println(String.format("%s %s",
+                        formatter.format(new Date()), event.toString()));
+            }
+        });
+        // there's really no way to stop, essentially we just block indefinitely here and wait
+        // for user to press Ctrl+C
+        synchronized (mQuitLock) {
+            try {
+                mQuitLock.wait();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        automationWrapper.disconnect();
+    }
+}
diff --git a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java
new file mode 100644
index 0000000..bc1d948
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/Launcher.java
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.uiautomator;
+
+import android.os.Process;
+
+import java.util.Arrays;
+
+/**
+ * Entry point into the uiautomator command line
+ *
+ * This class maintains the list of sub commands, and redirect the control into it based on the
+ * command line arguments. It also prints out help arguments for each sub commands.
+ *
+ * To add a new sub command, implement {@link Command} and add an instance into COMMANDS array
+ */
+public class Launcher {
+
+    /**
+     * A simple abstraction class for supporting generic sub commands
+     */
+    public static abstract class Command {
+        private String mName;
+
+        public Command(String name) {
+            mName = name;
+        }
+
+        /**
+         * Returns the name of the sub command
+         * @return
+         */
+        public String name() {
+            return mName;
+        }
+
+        /**
+         * Returns a one-liner of the function of this command
+         * @return
+         */
+        public abstract String shortHelp();
+
+        /**
+         * Returns a detailed explanation of the command usage
+         *
+         * Usage may have multiple lines, indentation of 4 spaces recommended.
+         * @return
+         */
+        public abstract String detailedOptions();
+
+        /**
+         * Starts the command with the provided arguments
+         * @param args
+         */
+        public abstract void run(String args[]);
+    }
+
+    public static void main(String[] args) {
+        // show a meaningful process name in `ps`
+        Process.setArgV0("uiautomator");
+        if (args.length >= 1) {
+            Command command = findCommand(args[0]);
+            if (command != null) {
+                String[] args2 = {};
+                if (args.length > 1) {
+                    // consume the first arg
+                    args2 = Arrays.copyOfRange(args, 1, args.length);
+                }
+                command.run(args2);
+                return;
+            }
+        }
+        HELP_COMMAND.run(args);
+    }
+
+    private static Command findCommand(String name) {
+        for (Command command : COMMANDS) {
+            if (command.name().equals(name)) {
+                return command;
+            }
+        }
+        return null;
+    }
+
+    private static Command HELP_COMMAND = new Command("help") {
+        @Override
+        public void run(String[] args) {
+            System.err.println("Usage: uiautomator <subcommand> [options]\n");
+            System.err.println("Available subcommands:\n");
+            for (Command command : COMMANDS) {
+                String shortHelp = command.shortHelp();
+                String detailedOptions = command.detailedOptions();
+                if (shortHelp == null) {
+                    shortHelp = "";
+                }
+                if (detailedOptions == null) {
+                    detailedOptions = "";
+                }
+                System.err.println(String.format("%s: %s", command.name(), shortHelp));
+                System.err.println(detailedOptions);
+            }
+        }
+
+        @Override
+        public String detailedOptions() {
+            return null;
+        }
+
+        @Override
+        public String shortHelp() {
+            return "displays help message";
+        }
+    };
+
+    private static Command[] COMMANDS = new Command[] {
+        HELP_COMMAND,
+        new RunTestCommand(),
+        new DumpCommand(),
+        new EventsCommand(),
+    };
+}
\ No newline at end of file
diff --git a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
new file mode 100644
index 0000000..65611ab
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
@@ -0,0 +1,258 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.uiautomator;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.commands.uiautomator.Launcher.Command;
+import com.android.uiautomator.testrunner.UiAutomatorTestRunner;
+
+import dalvik.system.DexFile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * Implementation of the runtest sub command
+ *
+ */
+public class RunTestCommand extends Command {
+    private static final String LOGTAG = RunTestCommand.class.getSimpleName();
+
+    private static final String OUTPUT_SIMPLE = "simple";
+    private static final String OUTPUT_FORMAT_KEY = "outputFormat";
+    private static final String CLASS_PARAM = "class";
+    private static final String JARS_PARAM = "jars";
+    private static final String DEBUG_PARAM = "debug";
+    private static final String RUNNER_PARAM = "runner";
+    private static final String CLASS_SEPARATOR = ",";
+    private static final String JARS_SEPARATOR = ":";
+    private static final int ARG_OK = 0;
+    private static final int ARG_FAIL_INCOMPLETE_E = -1;
+    private static final int ARG_FAIL_INCOMPLETE_C = -2;
+    private static final int ARG_FAIL_NO_CLASS = -3;
+    private static final int ARG_FAIL_RUNNER = -4;
+    private static final int ARG_FAIL_UNSUPPORTED = -99;
+
+    private final Bundle mParams = new Bundle();
+    private final List<String> mTestClasses = new ArrayList<String>();
+    private boolean mDebug;
+    private boolean mMonkey = false;
+    private String mRunnerClassName;
+    private UiAutomatorTestRunner mRunner;
+
+    public RunTestCommand() {
+        super("runtest");
+    }
+
+    @Override
+    public void run(String[] args) {
+        int ret = parseArgs(args);
+        switch (ret) {
+            case ARG_FAIL_INCOMPLETE_C:
+                System.err.println("Incomplete '-c' parameter.");
+                System.exit(ARG_FAIL_INCOMPLETE_C);
+                break;
+            case ARG_FAIL_INCOMPLETE_E:
+                System.err.println("Incomplete '-e' parameter.");
+                System.exit(ARG_FAIL_INCOMPLETE_E);
+                break;
+            case ARG_FAIL_UNSUPPORTED:
+                System.err.println("Unsupported standalone parameter.");
+                System.exit(ARG_FAIL_UNSUPPORTED);
+                break;
+            default:
+                break;
+        }
+        if (mTestClasses.isEmpty()) {
+            addTestClassesFromJars();
+            if (mTestClasses.isEmpty()) {
+                System.err.println("No test classes found.");
+                System.exit(ARG_FAIL_NO_CLASS);
+            }
+        }
+        getRunner().run(mTestClasses, mParams, mDebug, mMonkey);
+    }
+
+    private int parseArgs(String[] args) {
+        // we are parsing for these parameters:
+        // -e <key> <value>
+        // key-value pairs
+        // special ones are:
+        // key is "class", parameter is passed onto JUnit as class name to run
+        // key is "debug", parameter will determine whether to wait for debugger
+        // to attach
+        // -c <class name>
+        // -s turns on the simple output format
+        // equivalent to -e class <class name>, i.e. passed onto JUnit
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-e")) {
+                if (i + 2 < args.length) {
+                    String key = args[++i];
+                    String value = args[++i];
+                    if (CLASS_PARAM.equals(key)) {
+                        addTestClasses(value);
+                    } else if (DEBUG_PARAM.equals(key)) {
+                        mDebug = "true".equals(value) || "1".equals(value);
+                    } else if (RUNNER_PARAM.equals(key)) {
+                        mRunnerClassName = value;
+                    } else {
+                        mParams.putString(key, value);
+                    }
+                } else {
+                    return ARG_FAIL_INCOMPLETE_E;
+                }
+            } else if (args[i].equals("-c")) {
+                if (i + 1 < args.length) {
+                    addTestClasses(args[++i]);
+                } else {
+                    return ARG_FAIL_INCOMPLETE_C;
+                }
+            } else if (args[i].equals("--monkey")) {
+                mMonkey = true;
+            } else if (args[i].equals("-s")) {
+                mParams.putString(OUTPUT_FORMAT_KEY, OUTPUT_SIMPLE);
+            } else {
+                return ARG_FAIL_UNSUPPORTED;
+            }
+        }
+        return ARG_OK;
+    }
+
+    protected UiAutomatorTestRunner getRunner() {
+        if (mRunner != null) {
+            return mRunner;
+        }
+
+        if (mRunnerClassName == null) {
+            mRunner = new UiAutomatorTestRunner();
+            return mRunner;
+        }
+        // use reflection to get the runner
+        Object o = null;
+        try {
+            Class<?> clazz = Class.forName(mRunnerClassName);
+            o = clazz.newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            System.err.println("Cannot find runner: " + mRunnerClassName);
+            System.exit(ARG_FAIL_RUNNER);
+        } catch (InstantiationException ie) {
+            System.err.println("Cannot instantiate runner: " + mRunnerClassName);
+            System.exit(ARG_FAIL_RUNNER);
+        } catch (IllegalAccessException iae) {
+            System.err.println("Constructor of runner " + mRunnerClassName + " is not accessibile");
+            System.exit(ARG_FAIL_RUNNER);
+        }
+        try {
+            UiAutomatorTestRunner runner = (UiAutomatorTestRunner)o;
+            mRunner = runner;
+            return runner;
+        } catch (ClassCastException cce) {
+            System.err.println("Specified runner is not subclass of "
+                    + UiAutomatorTestRunner.class.getSimpleName());
+            System.exit(ARG_FAIL_RUNNER);
+        }
+        // won't reach here
+        return null;
+    }
+
+    /**
+     * Add test classes from a potentially comma separated list
+     * @param classes
+     */
+    private void addTestClasses(String classes) {
+        String[] classArray = classes.split(CLASS_SEPARATOR);
+        for (String clazz : classArray) {
+            mTestClasses.add(clazz);
+        }
+    }
+
+    /**
+     * Add test classes from jars passed on the command line. Use this if nothing was explicitly
+     * specified on the command line.
+     */
+    private void addTestClassesFromJars() {
+        String jars = mParams.getString(JARS_PARAM);
+        if (jars == null) return;
+
+        String[] jarFileNames = jars.split(JARS_SEPARATOR);
+        for (String fileName : jarFileNames) {
+            fileName = fileName.trim();
+            if (fileName.isEmpty()) continue;
+            try {
+                DexFile dexFile = new DexFile(fileName);
+                for(Enumeration<String> e = dexFile.entries(); e.hasMoreElements();) {
+                    String className = e.nextElement();
+                    if (isTestClass(className)) {
+                        mTestClasses.add(className);
+                    }
+                }
+                dexFile.close();
+            } catch (IOException e) {
+                Log.w(LOGTAG, String.format("Could not read %s: %s", fileName, e.getMessage()));
+            }
+        }
+    }
+
+    /**
+     * Tries to determine if a given class is a test class. A test class has to inherit from
+     * UiAutomator test case and it must be a top-level class.
+     * @param className
+     * @return
+     */
+    private boolean isTestClass(String className) {
+        try {
+            Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
+            if (clazz.getEnclosingClass() != null) return false;
+            return getRunner().getTestCaseFilter().accept(clazz);
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public String detailedOptions() {
+        return "    runtest <class spec> [options]\n"
+            + "    <class spec>: <JARS> < -c <CLASSES> | -e class <CLASSES> >\n"
+            + "      <JARS>: a list of jar files containing test classes and dependencies. If\n"
+            + "        the path is relative, it's assumed to be under /data/local/tmp. Use\n"
+            + "        absolute path if the file is elsewhere. Multiple files can be\n"
+            + "        specified, separated by space.\n"
+            + "      <CLASSES>: a list of test class names to run, separated by comma. To\n"
+            + "        a single method, use TestClass#testMethod format. The -e or -c option\n"
+            + "        may be repeated. This option is not required and if not provided then\n"
+            + "        all the tests in provided jars will be run automatically.\n"
+            + "    options:\n"
+            + "      --nohup: trap SIG_HUP, so test won't terminate even if parent process\n"
+            + "               is terminated, e.g. USB is disconnected.\n"
+            + "      -e debug [true|false]: wait for debugger to connect before starting.\n"
+            + "      -e runner [CLASS]: use specified test runner class instead. If\n"
+            + "        unspecified, framework default runner will be used.\n"
+            + "      -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.\n"
+            + "        May be repeated.\n"
+            + "      -e outputFormat simple | -s: enabled less verbose JUnit style output.\n";
+    }
+
+    @Override
+    public String shortHelp() {
+        return "executes UI automation tests";
+    }
+
+}
diff --git a/cmds/uiautomator/cmds/uiautomator/uiautomator b/cmds/uiautomator/cmds/uiautomator/uiautomator
new file mode 100755
index 0000000..fe2c735
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/uiautomator
@@ -0,0 +1,123 @@
+#
+# 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.
+#
+# Script to start "uiautomator" on the device
+#
+# The script does a couple of things:
+# * Use an alternative dalvik cache when running as non-root. Jar file needs
+#   to be dexopt'd to run in Dalvik. For plain jar files, this is done at first
+#   use. shell user does not have write permission to default system Dalvik
+#   cache so we redirect to an alternative cache
+# * special processing for subcommand 'runtest':
+#    * '--nohup' allows process continue to run even if parent process that
+#      started it has already terminated. We parse for this parameter and set
+#      signal trap. This is useful for testing with USB disconnected
+#    * all jar files that the test classes resides in, or dependent on are
+#      provided on command line and exported to CLASSPATH environment variable
+#      before starting the Java code. This offloads the task of class loading
+#      and resolving of cross jar class dependency to Dalvik
+#    * all other subcommand or options are directly passed into Java code for
+#      further parsing
+
+export run_base=/data/local/tmp
+export base=/system
+
+# if not running as root, trick dalvik into using an alternative dex cache
+if [ ${USER_ID} -ne 0 ]; then
+  tmp_cache=${run_base}/dalvik-cache
+
+  if [ ! -d ${tmp_cache} ]; then
+    mkdir -p ${tmp_cache}
+  fi
+
+  export ANDROID_DATA=${run_base}
+fi
+
+# take first parameter as the command
+cmd=${1}
+
+if [ -z "${1}" ]; then
+  cmd="help"
+fi
+
+# strip the command parameter
+if [ -n "${1}" ]; then
+  shift
+fi
+
+CLASSPATH=/system/framework/android.test.runner.jar:${base}/framework/uiautomator.jar
+
+# eventually args will be what get passed down to Java code
+args=
+# we also pass the list of jar files, so we can extract class names for tests
+# if they are not explicitly specified
+jars=
+
+# special case pre-processing for 'runtest' command
+if [ "${cmd}" == "runtest" ]; then
+  # first parse the jar paths
+  while [ true ]; do
+    if [ -z "${1}" ] && [ -z "${jars}" ]; then
+      echo "Error: more parameters expected for runtest; please see usage for details"
+      cmd="help"
+      break
+    fi
+    if [ -z "${1}" ]; then
+      break
+    fi
+    jar=${1}
+    if [ "${1:0:1}" = "-" ]; then
+      # we are done with jars, starting with parameters now
+      break
+    fi
+    # if relative path, append the default path prefix
+    if [ "${1:0:1}" != "/" ]; then
+      jar=${run_base}/${1}
+    fi
+    # about to add the file to class path, check if it's valid
+    if [ ! -f ${jar} ]; then
+      echo "Error: ${jar} does not exist"
+      # force to print help message
+      cmd="help"
+      break
+    fi
+    jars=${jars}:${jar}
+    # done processing current arg, moving on
+    shift
+  done
+  # look for --nohup: if found, consume it and trap SIG_HUP, otherwise just
+  # append the arg to args
+  while [ -n "${1}" ]; do
+    if [ "${1}" = "--nohup" ]; then
+      trap "" HUP
+      shift
+    else
+      args="${args} ${1}"
+      shift
+    fi
+  done
+else
+  # if cmd is not 'runtest', just take the rest of the args
+  args=${@}
+fi
+
+args="${cmd} ${args}"
+if [ -n "${jars}" ]; then
+   args="${args} -e jars ${jars}"
+fi
+
+CLASSPATH=${CLASSPATH}:${jars}
+export CLASSPATH
+exec app_process ${base}/bin com.android.commands.uiautomator.Launcher ${args}
diff --git a/cmds/uiautomator/instrumentation/Android.mk b/cmds/uiautomator/instrumentation/Android.mk
new file mode 100644
index 0000000..0c93b4c
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/Android.mk
@@ -0,0 +1,29 @@
+#
+# 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_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, testrunner-src) \
+    $(call all-java-files-under, ../library/core-src)
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_MODULE := uiautomator-instrumentation
+# TODO: change this to 18 when it's available
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
new file mode 100644
index 0000000..1d4fb93
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/core/InstrumentationUiAutomatorBridge.java
@@ -0,0 +1,60 @@
+/*
+ * 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.uiautomator.core;
+
+import android.app.Service;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.os.PowerManager;
+import android.view.Display;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+
+/**
+ * @hide
+ */
+public class InstrumentationUiAutomatorBridge extends UiAutomatorBridge {
+
+    private final Context mContext;
+
+    public InstrumentationUiAutomatorBridge(Context context, UiAutomation uiAutomation) {
+        super(uiAutomation);
+        mContext = context;
+    }
+
+    public Display getDefaultDisplay() {
+        WindowManager windowManager = (WindowManager)
+                mContext.getSystemService(Service.WINDOW_SERVICE);
+        return windowManager.getDefaultDisplay();
+    }
+
+    @Override
+    public int getRotation() {
+        return getDefaultDisplay().getRotation();
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        PowerManager pm = (PowerManager)
+                mContext.getSystemService(Service.POWER_SERVICE);
+        return pm.isScreenOn();
+    }
+
+    public long getSystemLongPressTime() {
+        return ViewConfiguration.getLongPressTimeout();
+    }
+}
diff --git a/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
new file mode 100644
index 0000000..f0c60d2
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import android.os.Bundle;
+
+/**
+ * Provides auxiliary support for running test cases
+ *
+ * @since API Level 16
+ */
+public interface IAutomationSupport {
+
+    /**
+     * Allows the running test cases to send out interim status
+     *
+     * @param resultCode
+     * @param status status report, consisting of key value pairs
+     * @since API Level 16
+     */
+    public void sendStatus(int resultCode, Bundle status);
+
+}
diff --git a/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java
new file mode 100644
index 0000000..a70586e
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/InstrumentationAutomationSupport.java
@@ -0,0 +1,40 @@
+/*
+ * 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.uiautomator.testrunner;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+
+/**
+ * A wrapper around {@link Instrumentation} to provide sendStatus function
+ *
+ * Provided for backwards compatibility purpose. New code should use
+ * {@link Instrumentation#sendStatus(int, Bundle)} instead.
+ *
+ */
+class InstrumentationAutomationSupport implements IAutomationSupport {
+
+    private Instrumentation mInstrumentation;
+
+    InstrumentationAutomationSupport(Instrumentation instrumentation) {
+        mInstrumentation = instrumentation;
+    }
+
+    @Override
+    public void sendStatus(int resultCode, Bundle status) {
+        mInstrumentation.sendStatus(resultCode, status);
+    }
+}
diff --git a/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java
new file mode 100644
index 0000000..ae763f2
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorInstrumentationTestRunner.java
@@ -0,0 +1,78 @@
+/*
+ * 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.uiautomator.testrunner;
+
+import android.test.AndroidTestRunner;
+import android.test.InstrumentationTestRunner;
+
+import com.android.uiautomator.core.Tracer;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+/**
+ * Test runner for {@link UiAutomatorTestCase}s. Such tests are executed
+ * on the device and have access to an applications context.
+ */
+public class UiAutomatorInstrumentationTestRunner extends InstrumentationTestRunner {
+
+    @Override
+    public void onStart() {
+        // process runner arguments before test starts
+        String traceType = getArguments().getString("traceOutputMode");
+        if(traceType != null) {
+            Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
+            if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
+                String filename = getArguments().getString("traceLogFilename");
+                if (filename == null) {
+                    throw new RuntimeException("Name of log file not specified. " +
+                            "Please specify it using traceLogFilename parameter");
+                }
+                Tracer.getInstance().setOutputFilename(filename);
+            }
+            Tracer.getInstance().setOutputMode(mode);
+        }
+        super.onStart();
+    }
+
+    @Override
+    protected AndroidTestRunner getAndroidTestRunner() {
+        AndroidTestRunner testRunner = super.getAndroidTestRunner();
+        testRunner.addTestListener(new TestListener() {
+            @Override
+            public void startTest(Test test) {
+                if (test instanceof UiAutomatorTestCase) {
+                    ((UiAutomatorTestCase)test).initialize(getArguments());
+                }
+            }
+
+            @Override
+            public void endTest(Test test) {
+            }
+
+            @Override
+            public void addFailure(Test test, AssertionFailedError e) {
+            }
+
+            @Override
+            public void addError(Test test, Throwable t) {
+            }
+        });
+        return testRunner;
+    }
+}
diff --git a/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
new file mode 100644
index 0000000..b5f21c9
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * 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.uiautomator.testrunner;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+
+import com.android.uiautomator.core.InstrumentationUiAutomatorBridge;
+import com.android.uiautomator.core.UiDevice;
+
+/**
+ * UI Automator test case that is executed on the device.
+ */
+public class UiAutomatorTestCase extends InstrumentationTestCase {
+
+    private Bundle mParams;
+    private IAutomationSupport mAutomationSupport;
+
+    /**
+     * Get current instance of {@link UiDevice}. Works similar to calling the static
+     * {@link UiDevice#getInstance()} from anywhere in the test classes.
+     * @since API Level 16
+     */
+    public UiDevice getUiDevice() {
+        return UiDevice.getInstance();
+    }
+
+    /**
+     * Get command line parameters. On the command line when passing <code>-e key value</code>
+     * pairs, the {@link Bundle} will have the key value pairs conveniently available to the
+     * tests.
+     * @since API Level 16
+     */
+    public Bundle getParams() {
+        return mParams;
+    }
+
+    void setAutomationSupport(IAutomationSupport automationSupport) {
+        mAutomationSupport = automationSupport;
+    }
+
+    /**
+     * Provides support for running tests to report interim status
+     *
+     * @return IAutomationSupport
+     * @since API Level 16
+     * @deprecated Use {@link Instrumentation#sendStatus(int, Bundle)} instead
+     */
+    public IAutomationSupport getAutomationSupport() {
+        if (mAutomationSupport == null) {
+            mAutomationSupport = new InstrumentationAutomationSupport(getInstrumentation());
+        }
+        return mAutomationSupport;
+    }
+
+    /**
+     * Initializes this test case.
+     *
+     * @param params Instrumentation arguments.
+     */
+    void initialize(Bundle params) {
+        mParams = params;
+
+        // check if this is a monkey test mode
+        String monkeyVal = mParams.getString("monkey");
+        if (monkeyVal != null) {
+            // only if the monkey key is specified, we alter the state of monkey
+            // else we should leave things as they are.
+            getInstrumentation().getUiAutomation().setRunAsMonkey(Boolean.valueOf(monkeyVal));
+        }
+
+        UiDevice.getInstance().initialize(new InstrumentationUiAutomatorBridge(
+                getInstrumentation().getContext(),
+                getInstrumentation().getUiAutomation()));
+    }
+
+    /**
+     * Calls {@link SystemClock#sleep(long)} to sleep
+     * @param ms is in milliseconds.
+     * @since API Level 16
+     */
+    public void sleep(long ms) {
+        SystemClock.sleep(ms);
+    }
+}
diff --git a/cmds/uiautomator/library/Android.mk b/cmds/uiautomator/library/Android.mk
new file mode 100644
index 0000000..7cc0884
--- /dev/null
+++ b/cmds/uiautomator/library/Android.mk
@@ -0,0 +1,132 @@
+#
+# 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)
+
+uiautomator.core_src_files := $(call all-java-files-under, core-src) \
+	$(call all-java-files-under, testrunner-src)
+uiautomator.core_java_libraries := android.test.runner core-junit
+
+uiautomator_internal_api_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_api.txt
+uiautomator_internal_removed_api_file := \
+    $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_removed_api.txt
+
+###############################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_MODULE := uiautomator.core
+LOCAL_JAVA_LIBRARIES := android.test.runner
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+###############################################
+# Generate the stub source files
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(uiautomator.core_src_files)
+LOCAL_JAVA_LIBRARIES := $(uiautomator.core_java_libraries)
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_DROIDDOC_SOURCE_PATH := $(LOCAL_PATH)/core-src \
+	$(LOCAL_PATH)/testrunner-src
+LOCAL_DROIDDOC_HTML_DIR :=
+
+LOCAL_DROIDDOC_OPTIONS:= \
+    -stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_uiautomator_intermediates/src \
+    -stubpackages com.android.uiautomator.core:com.android.uiautomator.testrunner \
+    -api $(uiautomator_internal_api_file) \
+    -removedApi $(uiautomator_internal_removed_api_file)
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sdk
+LOCAL_UNINSTALLABLE_MODULE := true
+
+LOCAL_MODULE := uiautomator-stubs
+
+include $(BUILD_DROIDDOC)
+uiautomator_stubs_stamp := $(full_target)
+$(uiautomator_internal_api_file) : $(full_target)
+
+###############################################
+# Build the stub source files into a jar.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android_uiautomator
+LOCAL_JAVA_LIBRARIES := $(uiautomator.core_java_libraries)
+LOCAL_SOURCE_FILES_ALL_GENERATED := true
+include $(BUILD_STATIC_JAVA_LIBRARY)
+# Make sure to run droiddoc first to generate the stub source files.
+$(full_classes_compiled_jar) : $(uiautomator_stubs_stamp)
+uiautomator_stubs_jar := $(full_classes_compiled_jar)
+
+###############################################
+# API check
+# Please refer to build/core/tasks/apicheck.mk.
+uiautomator_api_dir := frameworks/base/cmds/uiautomator/api
+last_released_sdk_version := $(lastword $(call numerically_sort, \
+    $(filter-out current, \
+        $(patsubst $(uiautomator_api_dir)/%.txt,%, $(wildcard $(uiautomator_api_dir)/*.txt)) \
+    )))
+
+checkapi_last_error_level_flags := \
+    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18
+
+# Check that the API we're building hasn't broken the last-released SDK version.
+$(eval $(call check-api, \
+    uiautomator-checkapi-last, \
+    $(uiautomator_api_dir)/$(last_released_sdk_version).txt, \
+    $(uiautomator_internal_api_file), \
+    $(uiautomator_api_dir)/removed.txt, \
+    $(uiautomator_internal_removed_api_file), \
+    $(checkapi_last_error_level_flags), \
+    cat $(LOCAL_PATH)/apicheck_msg_last.txt, \
+    $(uiautomator_stubs_jar), \
+    $(uiautomator_stubs_stamp)))
+
+checkapi_current_error_level_flags := \
+    -error 2 -error 3 -error 4 -error 5 -error 6 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
+    -error 25
+
+# Check that the API we're building hasn't changed from the not-yet-released
+# SDK version.
+$(eval $(call check-api, \
+    uiautomator-checkapi-current, \
+    $(uiautomator_api_dir)/current.txt, \
+    $(uiautomator_internal_api_file), \
+    $(uiautomator_api_dir)/removed.txt, \
+    $(uiautomator_internal_removed_api_file), \
+    $(checkapi_current_error_level_flags), \
+    cat $(LOCAL_PATH)/apicheck_msg_current.txt, \
+    $(uiautomator_stubs_jar), \
+    $(uiautomator_stubs_stamp)))
+
+.PHONY: update-uiautomator-api
+update-uiautomator-api: PRIVATE_API_DIR := $(uiautomator_api_dir)
+update-uiautomator-api: PRIVATE_REMOVED_API_FILE := $(uiautomator_internal_removed_api_file)
+update-uiautomator-api: $(uiautomator_internal_api_file) | $(ACP)
+	@echo Copying uiautomator current.txt
+	$(hide) $(ACP) $< $(PRIVATE_API_DIR)/current.txt
+	@echo Copying uiautomator removed.txt
+	$(hide) $(ACP) $(PRIVATE_REMOVED_API_FILE) $(PRIVATE_API_DIR)/removed.txt
+###############################################
+# clean up temp vars
+uiautomator.core_src_files :=
+uiautomator.core_java_libraries :=
+uiautomator_stubs_stamp :=
+uiautomator_internal_api_file :=
+uiautomator_stubs_jar :=
+uiautomator_api_dir :=
+checkapi_last_error_level_flags :=
+checkapi_current_error_level_flags :=
diff --git a/cmds/uiautomator/library/apicheck_msg_current.txt b/cmds/uiautomator/library/apicheck_msg_current.txt
new file mode 100644
index 0000000..989248d
--- /dev/null
+++ b/cmds/uiautomator/library/apicheck_msg_current.txt
@@ -0,0 +1,17 @@
+
+******************************
+You have tried to change the API from what has been previously approved.
+
+To make these errors go away, you have two choices:
+   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
+      errors above.
+
+   2) You can update current.txt by executing the following command:
+         make update-uiautomator-api
+
+      To submit the revised current.txt to the main Android repository,
+      you will need approval.
+******************************
+
+
+
diff --git a/cmds/uiautomator/library/apicheck_msg_last.txt b/cmds/uiautomator/library/apicheck_msg_last.txt
new file mode 100644
index 0000000..2993157
--- /dev/null
+++ b/cmds/uiautomator/library/apicheck_msg_last.txt
@@ -0,0 +1,7 @@
+
+******************************
+You have tried to change the API from what has been previously released in
+an SDK.  Please fix the errors listed above.
+******************************
+
+
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
new file mode 100644
index 0000000..63c51e8
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.os.Environment;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Xml;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ *
+ * @hide
+ */
+public class AccessibilityNodeInfoDumper {
+
+    private static final String LOGTAG = AccessibilityNodeInfoDumper.class.getSimpleName();
+    private static final String[] NAF_EXCLUDED_CLASSES = new String[] {
+            android.widget.GridView.class.getName(), android.widget.GridLayout.class.getName(),
+            android.widget.ListView.class.getName(), android.widget.TableLayout.class.getName()
+    };
+
+    /**
+     * Using {@link AccessibilityNodeInfo} this method will walk the layout hierarchy
+     * and generates an xml dump into the /data/local/window_dump.xml
+     * @param root The root accessibility node.
+     * @param rotation The rotaion of current display
+     * @param width The pixel width of current display
+     * @param height The pixel height of current display
+     */
+    public static void dumpWindowToFile(AccessibilityNodeInfo root, int rotation,
+            int width, int height) {
+        File baseDir = new File(Environment.getDataDirectory(), "local");
+        if (!baseDir.exists()) {
+            baseDir.mkdir();
+            baseDir.setExecutable(true, false);
+            baseDir.setWritable(true, false);
+            baseDir.setReadable(true, false);
+        }
+        dumpWindowToFile(root,
+                new File(new File(Environment.getDataDirectory(), "local"), "window_dump.xml"),
+                rotation, width, height);
+    }
+
+    /**
+     * Using {@link AccessibilityNodeInfo} this method will walk the layout hierarchy
+     * and generates an xml dump to the location specified by <code>dumpFile</code>
+     * @param root The root accessibility node.
+     * @param dumpFile The file to dump to.
+     * @param rotation The rotaion of current display
+     * @param width The pixel width of current display
+     * @param height The pixel height of current display
+     */
+    public static void dumpWindowToFile(AccessibilityNodeInfo root, File dumpFile, int rotation,
+            int width, int height) {
+        if (root == null) {
+            return;
+        }
+        final long startTime = SystemClock.uptimeMillis();
+        try {
+            FileWriter writer = new FileWriter(dumpFile);
+            XmlSerializer serializer = Xml.newSerializer();
+            StringWriter stringWriter = new StringWriter();
+            serializer.setOutput(stringWriter);
+            serializer.startDocument("UTF-8", true);
+            serializer.startTag("", "hierarchy");
+            serializer.attribute("", "rotation", Integer.toString(rotation));
+            dumpNodeRec(root, serializer, 0, width, height);
+            serializer.endTag("", "hierarchy");
+            serializer.endDocument();
+            writer.write(stringWriter.toString());
+            writer.close();
+        } catch (IOException e) {
+            Log.e(LOGTAG, "failed to dump window to file", e);
+        }
+        final long endTime = SystemClock.uptimeMillis();
+        Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms");
+    }
+
+    private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index,
+            int width, int height) throws IOException {
+        serializer.startTag("", "node");
+        if (!nafExcludedClass(node) && !nafCheck(node))
+            serializer.attribute("", "NAF", Boolean.toString(true));
+        serializer.attribute("", "index", Integer.toString(index));
+        serializer.attribute("", "text", safeCharSeqToString(node.getText()));
+        serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName()));
+        serializer.attribute("", "class", safeCharSeqToString(node.getClassName()));
+        serializer.attribute("", "package", safeCharSeqToString(node.getPackageName()));
+        serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription()));
+        serializer.attribute("", "checkable", Boolean.toString(node.isCheckable()));
+        serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
+        serializer.attribute("", "clickable", Boolean.toString(node.isClickable()));
+        serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
+        serializer.attribute("", "focusable", Boolean.toString(node.isFocusable()));
+        serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
+        serializer.attribute("", "scrollable", Boolean.toString(node.isScrollable()));
+        serializer.attribute("", "long-clickable", Boolean.toString(node.isLongClickable()));
+        serializer.attribute("", "password", Boolean.toString(node.isPassword()));
+        serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
+        serializer.attribute("", "bounds", AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(
+                node, width, height).toShortString());
+        int count = node.getChildCount();
+        for (int i = 0; i < count; i++) {
+            AccessibilityNodeInfo child = node.getChild(i);
+            if (child != null) {
+                if (child.isVisibleToUser()) {
+                    dumpNodeRec(child, serializer, i, width, height);
+                    child.recycle();
+                } else {
+                    Log.i(LOGTAG, String.format("Skipping invisible child: %s", child.toString()));
+                }
+            } else {
+                Log.i(LOGTAG, String.format("Null child %d/%d, parent: %s",
+                        i, count, node.toString()));
+            }
+        }
+        serializer.endTag("", "node");
+    }
+
+    /**
+     * The list of classes to exclude my not be complete. We're attempting to
+     * only reduce noise from standard layout classes that may be falsely
+     * configured to accept clicks and are also enabled.
+     *
+     * @param node
+     * @return true if node is excluded.
+     */
+    private static boolean nafExcludedClass(AccessibilityNodeInfo node) {
+        String className = safeCharSeqToString(node.getClassName());
+        for(String excludedClassName : NAF_EXCLUDED_CLASSES) {
+            if(className.endsWith(excludedClassName))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * We're looking for UI controls that are enabled, clickable but have no
+     * text nor content-description. Such controls configuration indicate an
+     * interactive control is present in the UI and is most likely not
+     * accessibility friendly. We refer to such controls here as NAF controls
+     * (Not Accessibility Friendly)
+     *
+     * @param node
+     * @return false if a node fails the check, true if all is OK
+     */
+    private static boolean nafCheck(AccessibilityNodeInfo node) {
+        boolean isNaf = node.isClickable() && node.isEnabled()
+                && safeCharSeqToString(node.getContentDescription()).isEmpty()
+                && safeCharSeqToString(node.getText()).isEmpty();
+
+        if (!isNaf)
+            return true;
+
+        // check children since sometimes the containing element is clickable
+        // and NAF but a child's text or description is available. Will assume
+        // such layout as fine.
+        return childNafCheck(node);
+    }
+
+    /**
+     * This should be used when it's already determined that the node is NAF and
+     * a further check of its children is in order. A node maybe a container
+     * such as LinerLayout and may be set to be clickable but have no text or
+     * content description but it is counting on one of its children to fulfill
+     * the requirement for being accessibility friendly by having one or more of
+     * its children fill the text or content-description. Such a combination is
+     * considered by this dumper as acceptable for accessibility.
+     *
+     * @param node
+     * @return false if node fails the check.
+     */
+    private static boolean childNafCheck(AccessibilityNodeInfo node) {
+        int childCount = node.getChildCount();
+        for (int x = 0; x < childCount; x++) {
+            AccessibilityNodeInfo childNode = node.getChild(x);
+
+            if (!safeCharSeqToString(childNode.getContentDescription()).isEmpty()
+                    || !safeCharSeqToString(childNode.getText()).isEmpty())
+                return true;
+
+            if (childNafCheck(childNode))
+                return true;
+        }
+        return false;
+    }
+
+    private static String safeCharSeqToString(CharSequence cs) {
+        if (cs == null)
+            return "";
+        else {
+            return stripInvalidXMLChars(cs);
+        }
+    }
+
+    private static String stripInvalidXMLChars(CharSequence cs) {
+        StringBuffer ret = new StringBuffer();
+        char ch;
+        /* http://www.w3.org/TR/xml11/#charsets
+        [#x1-#x8], [#xB-#xC], [#xE-#x1F], [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF],
+        [#x1FFFE-#x1FFFF], [#x2FFFE-#x2FFFF], [#x3FFFE-#x3FFFF],
+        [#x4FFFE-#x4FFFF], [#x5FFFE-#x5FFFF], [#x6FFFE-#x6FFFF],
+        [#x7FFFE-#x7FFFF], [#x8FFFE-#x8FFFF], [#x9FFFE-#x9FFFF],
+        [#xAFFFE-#xAFFFF], [#xBFFFE-#xBFFFF], [#xCFFFE-#xCFFFF],
+        [#xDFFFE-#xDFFFF], [#xEFFFE-#xEFFFF], [#xFFFFE-#xFFFFF],
+        [#x10FFFE-#x10FFFF].
+         */
+        for (int i = 0; i < cs.length(); i++) {
+            ch = cs.charAt(i);
+
+            if((ch >= 0x1 && ch <= 0x8) || (ch >= 0xB && ch <= 0xC) || (ch >= 0xE && ch <= 0x1F) ||
+                    (ch >= 0x7F && ch <= 0x84) || (ch >= 0x86 && ch <= 0x9f) ||
+                    (ch >= 0xFDD0 && ch <= 0xFDDF) || (ch >= 0x1FFFE && ch <= 0x1FFFF) ||
+                    (ch >= 0x2FFFE && ch <= 0x2FFFF) || (ch >= 0x3FFFE && ch <= 0x3FFFF) ||
+                    (ch >= 0x4FFFE && ch <= 0x4FFFF) || (ch >= 0x5FFFE && ch <= 0x5FFFF) ||
+                    (ch >= 0x6FFFE && ch <= 0x6FFFF) || (ch >= 0x7FFFE && ch <= 0x7FFFF) ||
+                    (ch >= 0x8FFFE && ch <= 0x8FFFF) || (ch >= 0x9FFFE && ch <= 0x9FFFF) ||
+                    (ch >= 0xAFFFE && ch <= 0xAFFFF) || (ch >= 0xBFFFE && ch <= 0xBFFFF) ||
+                    (ch >= 0xCFFFE && ch <= 0xCFFFF) || (ch >= 0xDFFFE && ch <= 0xDFFFF) ||
+                    (ch >= 0xEFFFE && ch <= 0xEFFFF) || (ch >= 0xFFFFE && ch <= 0xFFFFF) ||
+                    (ch >= 0x10FFFE && ch <= 0x10FFFF))
+                ret.append(".");
+            else
+                ret.append(ch);
+        }
+        return ret.toString();
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java
new file mode 100644
index 0000000..54835e3
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoHelper.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+import android.graphics.Rect;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * This class contains static helper methods to work with
+ * {@link AccessibilityNodeInfo}
+ */
+class AccessibilityNodeInfoHelper {
+
+    /**
+     * Returns the node's bounds clipped to the size of the display
+     *
+     * @param node
+     * @param width pixel width of the display
+     * @param height pixel height of the display
+     * @return null if node is null, else a Rect containing visible bounds
+     */
+    static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
+        if (node == null) {
+            return null;
+        }
+        // targeted node's bounds
+        Rect nodeRect = new Rect();
+        node.getBoundsInScreen(nodeRect);
+
+        Rect displayRect = new Rect();
+        displayRect.top = 0;
+        displayRect.left = 0;
+        displayRect.right = width;
+        displayRect.bottom = height;
+
+        nodeRect.intersect(displayRect);
+        return nodeRect;
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Configurator.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Configurator.java
new file mode 100644
index 0000000..249f404
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Configurator.java
@@ -0,0 +1,224 @@
+/*
+ * 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.uiautomator.core;
+
+/**
+ * Allows you to set key parameters for running uiautomator tests. The new
+ * settings take effect immediately and can be changed any time during a test run.
+ *
+ * To modify parameters using Configurator, first obtain an instance by calling
+ * {@link #getInstance()}. As a best practice, make sure you always save
+ * the original value of any parameter that you are modifying. After running your
+ * tests with the modified parameters, make sure to also restore
+ * the original parameter values, otherwise this will impact other tests cases.
+ * @since API Level 18
+ */
+public final class Configurator {
+    private long mWaitForIdleTimeout = 10 * 1000;
+    private long mWaitForSelector = 10 * 1000;
+    private long mWaitForActionAcknowledgment = 3 * 1000;
+
+    // The events for a scroll typically complete even before touchUp occurs.
+    // This short timeout to make sure we get the very last in cases where the above isn't true.
+    private long mScrollEventWaitTimeout = 200; // ms
+
+    // Default is inject as fast as we can
+    private long mKeyInjectionDelay = 0; // ms
+
+    // reference to self
+    private static Configurator sConfigurator;
+
+    private Configurator() {
+        /* hide constructor */
+    }
+
+    /**
+     * Retrieves a singleton instance of Configurator.
+     *
+     * @return Configurator instance
+     * @since API Level 18
+     */
+    public static Configurator getInstance() {
+        if (sConfigurator == null) {
+            sConfigurator = new Configurator();
+        }
+        return sConfigurator;
+    }
+
+    /**
+     * Sets the timeout for waiting for the user interface to go into an idle
+     * state before starting a uiautomator action.
+     *
+     * By default, all core uiautomator objects except {@link UiDevice} will perform
+     * this wait before starting to search for the widget specified by the
+     * object's {@link UiSelector}. Once the idle state is detected or the
+     * timeout elapses (whichever occurs first), the object will start to wait
+     * for the selector to find a match.
+     * See {@link #setWaitForSelectorTimeout(long)}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setWaitForIdleTimeout(long timeout) {
+        mWaitForIdleTimeout = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout used for waiting for the user interface to go
+     * into an idle state.
+     *
+     * By default, all core uiautomator objects except {@link UiDevice} will perform
+     * this wait before starting to search for the widget specified by the
+     * object's {@link UiSelector}. Once the idle state is detected or the
+     * timeout elapses (whichever occurs first), the object will start to wait
+     * for the selector to find a match.
+     * See {@link #setWaitForSelectorTimeout(long)}
+     *
+     * @return Current timeout value in milliseconds
+     * @since API Level 18
+     */
+    public long getWaitForIdleTimeout() {
+        return mWaitForIdleTimeout;
+    }
+
+    /**
+     * Sets the timeout for waiting for a widget to become visible in the user
+     * interface so that it can be matched by a selector.
+     *
+     * Because user interface content is dynamic, sometimes a widget may not
+     * be visible immediately and won't be detected by a selector. This timeout
+     * allows the uiautomator framework to wait for a match to be found, up until
+     * the timeout elapses.
+     *
+     * @param timeout Timeout value in milliseconds.
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setWaitForSelectorTimeout(long timeout) {
+        mWaitForSelector = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout for waiting for a widget to become visible in
+     * the user interface so that it can be matched by a selector.
+     *
+     * Because user interface content is dynamic, sometimes a widget may not
+     * be visible immediately and won't be detected by a selector. This timeout
+     * allows the uiautomator framework to wait for a match to be found, up until
+     * the timeout elapses.
+     *
+     * @return Current timeout value in milliseconds
+     * @since API Level 18
+     */
+    public long getWaitForSelectorTimeout() {
+        return mWaitForSelector;
+    }
+
+    /**
+     * Sets the timeout for waiting for an acknowledgement of an
+     * uiautomtor scroll swipe action.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to the scroll action, that lets the framework determine if
+     * the scroll action was successful. Generally, this timeout should not be modified.
+     * See {@link UiScrollable}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setScrollAcknowledgmentTimeout(long timeout) {
+        mScrollEventWaitTimeout = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the timeout for waiting for an acknowledgement of an
+     * uiautomtor scroll swipe action.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to the scroll action, that lets the framework determine if
+     * the scroll action was successful. Generally, this timeout should not be modified.
+     * See {@link UiScrollable}
+     *
+     * @return current timeout in milliseconds
+     * @since API Level 18
+     */
+    public long getScrollAcknowledgmentTimeout() {
+        return mScrollEventWaitTimeout;
+    }
+
+    /**
+     * Sets the timeout for waiting for an acknowledgment of generic uiautomator
+     * actions, such as clicks, text setting, and menu presses.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to an action, that lets the framework determine if the
+     * action was successful. Generally, this timeout should not be modified.
+     * See {@link UiObject}
+     *
+     * @param timeout Timeout value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setActionAcknowledgmentTimeout(long timeout) {
+        mWaitForActionAcknowledgment = timeout;
+        return this;
+    }
+
+    /**
+     * Gets the current timeout for waiting for an acknowledgment of generic
+     * uiautomator actions, such as clicks, text setting, and menu presses.
+     *
+     * The acknowledgment is an <a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html">AccessibilityEvent</a>,
+     * corresponding to an action, that lets the framework determine if the
+     * action was successful. Generally, this timeout should not be modified.
+     * See {@link UiObject}
+     *
+     * @return current timeout in milliseconds
+     * @since API Level 18
+     */
+    public long getActionAcknowledgmentTimeout() {
+        return mWaitForActionAcknowledgment;
+    }
+
+    /**
+     * Sets a delay between key presses when injecting text input.
+     * See {@link UiObject#setText(String)}
+     *
+     * @param delay Delay value in milliseconds
+     * @return self
+     * @since API Level 18
+     */
+    public Configurator setKeyInjectionDelay(long delay) {
+        mKeyInjectionDelay = delay;
+        return this;
+    }
+
+    /**
+     * Gets the current delay between key presses when injecting text input.
+     * See {@link UiObject#setText(String)}
+     *
+     * @return current delay in milliseconds
+     * @since API Level 18
+     */
+    public long getKeyInjectionDelay() {
+        return mKeyInjectionDelay;
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/InteractionController.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/InteractionController.java
new file mode 100644
index 0000000..73e46f1
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/InteractionController.java
@@ -0,0 +1,795 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityService;
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.graphics.Point;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.internal.util.Predicate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * The InteractionProvider is responsible for injecting user events such as touch events
+ * (includes swipes) and text key events into the system. To do so, all it needs to know about
+ * are coordinates of the touch events and text for the text input events.
+ * The InteractionController performs no synchronization. It will fire touch and text input events
+ * as fast as it receives them. All idle synchronization is performed prior to querying the
+ * hierarchy. See {@link QueryController}
+ */
+class InteractionController {
+
+    private static final String LOG_TAG = InteractionController.class.getSimpleName();
+
+    private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
+    private final KeyCharacterMap mKeyCharacterMap =
+            KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+
+    private final UiAutomatorBridge mUiAutomatorBridge;
+
+    private static final long REGULAR_CLICK_LENGTH = 100;
+
+    private long mDownTime;
+
+    // Inserted after each motion event injection.
+    private static final int MOTION_EVENT_INJECTION_DELAY_MILLIS = 5;
+
+    public InteractionController(UiAutomatorBridge bridge) {
+        mUiAutomatorBridge = bridge;
+    }
+
+    /**
+     * Predicate for waiting for any of the events specified in the mask
+     */
+    class WaitForAnyEventPredicate implements AccessibilityEventFilter {
+        int mMask;
+        WaitForAnyEventPredicate(int mask) {
+            mMask = mask;
+        }
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                return true;
+            }
+
+            // no match yet
+            return false;
+        }
+    }
+
+    /**
+     * Predicate for waiting for all the events specified in the mask and populating
+     * a ctor passed list with matching events. User of this Predicate must recycle
+     * all populated events in the events list.
+     */
+    class EventCollectingPredicate implements AccessibilityEventFilter {
+        int mMask;
+        List<AccessibilityEvent> mEventsList;
+
+        EventCollectingPredicate(int mask, List<AccessibilityEvent> events) {
+            mMask = mask;
+            mEventsList = events;
+        }
+
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                // For the events you need, always store a copy when returning false from
+                // predicates since the original will automatically be recycled after the call.
+                mEventsList.add(AccessibilityEvent.obtain(t));
+            }
+
+            // get more
+            return false;
+        }
+    }
+
+    /**
+     * Predicate for waiting for every event specified in the mask to be matched at least once
+     */
+    class WaitForAllEventPredicate implements AccessibilityEventFilter {
+        int mMask;
+        WaitForAllEventPredicate(int mask) {
+            mMask = mask;
+        }
+
+        @Override
+        public boolean accept(AccessibilityEvent t) {
+            // check current event in the list
+            if ((t.getEventType() & mMask) != 0) {
+                // remove from mask since this condition is satisfied
+                mMask &= ~t.getEventType();
+
+                // Since we're waiting for all events to be matched at least once
+                if (mMask != 0)
+                    return false;
+
+                // all matched
+                return true;
+            }
+
+            // no match yet
+            return false;
+        }
+    }
+
+    /**
+     * Helper used by methods to perform actions and wait for any accessibility events and return
+     * predicated on predefined filter.
+     *
+     * @param command
+     * @param filter
+     * @param timeout
+     * @return
+     */
+    private AccessibilityEvent runAndWaitForEvents(Runnable command,
+            AccessibilityEventFilter filter, long timeout) {
+
+        try {
+            return mUiAutomatorBridge.executeCommandAndWaitForAccessibilityEvent(command, filter,
+                    timeout);
+        } catch (TimeoutException e) {
+            Log.w(LOG_TAG, "runAndwaitForEvent timedout waiting for events");
+            return null;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "exception from executeCommandAndWaitForAccessibilityEvent", e);
+            return null;
+        }
+    }
+
+    /**
+     * Send keys and blocks until the first specified accessibility event.
+     *
+     * Most key presses will cause some UI change to occur. If the device is busy, this will
+     * block until the device begins to process the key press at which point the call returns
+     * and normal wait for idle processing may begin. If no events are detected for the
+     * timeout period specified, the call will return anyway with false.
+     *
+     * @param keyCode
+     * @param metaState
+     * @param eventType
+     * @param timeout
+     * @return true if events is received, otherwise false.
+     */
+    public boolean sendKeyAndWaitForEvent(final int keyCode, final int metaState,
+            final int eventType, long timeout) {
+        Runnable command = new Runnable() {
+            @Override
+            public void run() {
+                final long eventTime = SystemClock.uptimeMillis();
+                KeyEvent downEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
+                        keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                        InputDevice.SOURCE_KEYBOARD);
+                if (injectEventSync(downEvent)) {
+                    KeyEvent upEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP,
+                            keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                            InputDevice.SOURCE_KEYBOARD);
+                    injectEventSync(upEvent);
+                }
+            }
+        };
+
+        return runAndWaitForEvents(command, new WaitForAnyEventPredicate(eventType), timeout)
+                != null;
+    }
+
+    /**
+     * Clicks at coordinates without waiting for device idle. This may be used for operations
+     * that require stressing the target.
+     * @param x
+     * @param y
+     * @return true if the click executed successfully
+     */
+    public boolean clickNoSync(int x, int y) {
+        Log.d(LOG_TAG, "clickNoSync (" + x + ", " + y + ")");
+
+        if (touchDown(x, y)) {
+            SystemClock.sleep(REGULAR_CLICK_LENGTH);
+            if (touchUp(x, y))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Click at coordinates and blocks until either accessibility event TYPE_WINDOW_CONTENT_CHANGED
+     * or TYPE_VIEW_SELECTED are received.
+     *
+     * @param x
+     * @param y
+     * @param timeout waiting for event
+     * @return true if events are received, else false if timeout.
+     */
+    public boolean clickAndSync(final int x, final int y, long timeout) {
+
+        String logString = String.format("clickAndSync(%d, %d)", x, y);
+        Log.d(LOG_TAG, logString);
+
+        return runAndWaitForEvents(clickRunnable(x, y), new WaitForAnyEventPredicate(
+                AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED |
+                AccessibilityEvent.TYPE_VIEW_SELECTED), timeout) != null;
+    }
+
+    /**
+     * Clicks at coordinates and waits for for a TYPE_WINDOW_STATE_CHANGED event followed
+     * by TYPE_WINDOW_CONTENT_CHANGED. If timeout occurs waiting for TYPE_WINDOW_STATE_CHANGED,
+     * no further waits will be performed and the function returns.
+     * @param x
+     * @param y
+     * @param timeout waiting for event
+     * @return true if both events occurred in the expected order
+     */
+    public boolean clickAndWaitForNewWindow(final int x, final int y, long timeout) {
+        String logString = String.format("clickAndWaitForNewWindow(%d, %d)", x, y);
+        Log.d(LOG_TAG, logString);
+
+        return runAndWaitForEvents(clickRunnable(x, y), new WaitForAllEventPredicate(
+                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED |
+                AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED), timeout) != null;
+    }
+
+    /**
+     * Returns a Runnable for use in {@link #runAndWaitForEvents(Runnable, Predicate, long) to
+     * perform a click.
+     *
+     * @param x coordinate
+     * @param y coordinate
+     * @return Runnable
+     */
+    private Runnable clickRunnable(final int x, final int y) {
+        return new Runnable() {
+            @Override
+            public void run() {
+                if(touchDown(x, y)) {
+                    SystemClock.sleep(REGULAR_CLICK_LENGTH);
+                    touchUp(x, y);
+                }
+            }
+        };
+    }
+
+    /**
+     * Touches down for a long press at the specified coordinates.
+     *
+     * @param x
+     * @param y
+     * @return true if successful.
+     */
+    public boolean longTapNoSync(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "longTapNoSync (" + x + ", " + y + ")");
+        }
+
+        if (touchDown(x, y)) {
+            SystemClock.sleep(mUiAutomatorBridge.getSystemLongPressTime());
+            if(touchUp(x, y)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean touchDown(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchDown (" + x + ", " + y + ")");
+        }
+        mDownTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, mDownTime, MotionEvent.ACTION_DOWN, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        return injectEventSync(event);
+    }
+
+    private boolean touchUp(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchUp (" + x + ", " + y + ")");
+        }
+        final long eventTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, eventTime, MotionEvent.ACTION_UP, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        mDownTime = 0;
+        return injectEventSync(event);
+    }
+
+    private boolean touchMove(int x, int y) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "touchMove (" + x + ", " + y + ")");
+        }
+        final long eventTime = SystemClock.uptimeMillis();
+        MotionEvent event = MotionEvent.obtain(
+                mDownTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 1);
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        return injectEventSync(event);
+    }
+
+    /**
+     * Handle swipes in any direction where the result is a scroll event. This call blocks
+     * until the UI has fired a scroll event or timeout.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @return true if we are not at the beginning or end of the scrollable view.
+     */
+    public boolean scrollSwipe(final int downX, final int downY, final int upX, final int upY,
+            final int steps) {
+        Log.d(LOG_TAG, "scrollSwipe (" +  downX + ", " + downY + ", " + upX + ", "
+                + upY + ", " + steps +")");
+
+        Runnable command = new Runnable() {
+            @Override
+            public void run() {
+                swipe(downX, downY, upX, upY, steps);
+            }
+        };
+
+        // Collect all accessibility events generated during the swipe command and get the
+        // last event
+        ArrayList<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
+        runAndWaitForEvents(command,
+                new EventCollectingPredicate(AccessibilityEvent.TYPE_VIEW_SCROLLED, events),
+                Configurator.getInstance().getScrollAcknowledgmentTimeout());
+
+        AccessibilityEvent event = getLastMatchingEvent(events,
+                AccessibilityEvent.TYPE_VIEW_SCROLLED);
+
+        if (event == null) {
+            // end of scroll since no new scroll events received
+            recycleAccessibilityEvents(events);
+            return false;
+        }
+
+        // AdapterViews have indices we can use to check for the beginning.
+        boolean foundEnd = false;
+        if (event.getFromIndex() != -1 && event.getToIndex() != -1 && event.getItemCount() != -1) {
+            foundEnd = event.getFromIndex() == 0 ||
+                    (event.getItemCount() - 1) == event.getToIndex();
+            Log.d(LOG_TAG, "scrollSwipe reached scroll end: " + foundEnd);
+        } else if (event.getScrollX() != -1 && event.getScrollY() != -1) {
+            // Determine if we are scrolling vertically or horizontally.
+            if (downX == upX) {
+                // Vertical
+                foundEnd = event.getScrollY() == 0 ||
+                        event.getScrollY() == event.getMaxScrollY();
+                Log.d(LOG_TAG, "Vertical scrollSwipe reached scroll end: " + foundEnd);
+            } else if (downY == upY) {
+                // Horizontal
+                foundEnd = event.getScrollX() == 0 ||
+                        event.getScrollX() == event.getMaxScrollX();
+                Log.d(LOG_TAG, "Horizontal scrollSwipe reached scroll end: " + foundEnd);
+            }
+        }
+        recycleAccessibilityEvents(events);
+        return !foundEnd;
+    }
+
+    private AccessibilityEvent getLastMatchingEvent(List<AccessibilityEvent> events, int type) {
+        for (int x = events.size(); x > 0; x--) {
+            AccessibilityEvent event = events.get(x - 1);
+            if (event.getEventType() == type)
+                return event;
+        }
+        return null;
+    }
+
+    private void recycleAccessibilityEvents(List<AccessibilityEvent> events) {
+        for (AccessibilityEvent event : events)
+            event.recycle();
+        events.clear();
+    }
+
+    /**
+     * Handle swipes in any direction.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @return true if the swipe executed successfully
+     */
+    public boolean swipe(int downX, int downY, int upX, int upY, int steps) {
+        return swipe(downX, downY, upX, upY, steps, false /*drag*/);
+    }
+
+    /**
+     * Handle swipes/drags in any direction.
+     * @param downX
+     * @param downY
+     * @param upX
+     * @param upY
+     * @param steps
+     * @param drag when true, the swipe becomes a drag swipe
+     * @return true if the swipe executed successfully
+     */
+    public boolean swipe(int downX, int downY, int upX, int upY, int steps, boolean drag) {
+        boolean ret = false;
+        int swipeSteps = steps;
+        double xStep = 0;
+        double yStep = 0;
+
+        // avoid a divide by zero
+        if(swipeSteps == 0)
+            swipeSteps = 1;
+
+        xStep = ((double)(upX - downX)) / swipeSteps;
+        yStep = ((double)(upY - downY)) / swipeSteps;
+
+        // first touch starts exactly at the point requested
+        ret = touchDown(downX, downY);
+        if (drag)
+            SystemClock.sleep(mUiAutomatorBridge.getSystemLongPressTime());
+        for(int i = 1; i < swipeSteps; i++) {
+            ret &= touchMove(downX + (int)(xStep * i), downY + (int)(yStep * i));
+            if(ret == false)
+                break;
+            // set some known constant delay between steps as without it this
+            // become completely dependent on the speed of the system and results
+            // may vary on different devices. This guarantees at minimum we have
+            // a preset delay.
+            SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+        }
+        if (drag)
+            SystemClock.sleep(REGULAR_CLICK_LENGTH);
+        ret &= touchUp(upX, upY);
+        return(ret);
+    }
+
+    /**
+     * Performs a swipe between points in the Point array.
+     * @param segments is Point array containing at least one Point object
+     * @param segmentSteps steps to inject between two Points
+     * @return true on success
+     */
+    public boolean swipe(Point[] segments, int segmentSteps) {
+        boolean ret = false;
+        int swipeSteps = segmentSteps;
+        double xStep = 0;
+        double yStep = 0;
+
+        // avoid a divide by zero
+        if(segmentSteps == 0)
+            segmentSteps = 1;
+
+        // must have some points
+        if(segments.length == 0)
+            return false;
+
+        // first touch starts exactly at the point requested
+        ret = touchDown(segments[0].x, segments[0].y);
+        for(int seg = 0; seg < segments.length; seg++) {
+            if(seg + 1 < segments.length) {
+
+                xStep = ((double)(segments[seg+1].x - segments[seg].x)) / segmentSteps;
+                yStep = ((double)(segments[seg+1].y - segments[seg].y)) / segmentSteps;
+
+                for(int i = 1; i < swipeSteps; i++) {
+                    ret &= touchMove(segments[seg].x + (int)(xStep * i),
+                            segments[seg].y + (int)(yStep * i));
+                    if(ret == false)
+                        break;
+                    // set some known constant delay between steps as without it this
+                    // become completely dependent on the speed of the system and results
+                    // may vary on different devices. This guarantees at minimum we have
+                    // a preset delay.
+                    SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+                }
+            }
+        }
+        ret &= touchUp(segments[segments.length - 1].x, segments[segments.length -1].y);
+        return(ret);
+    }
+
+
+    public boolean sendText(String text) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "sendText (" + text + ")");
+        }
+
+        KeyEvent[] events = mKeyCharacterMap.getEvents(text.toCharArray());
+
+        if (events != null) {
+            long keyDelay = Configurator.getInstance().getKeyInjectionDelay();
+            for (KeyEvent event2 : events) {
+                // We have to change the time of an event before injecting it because
+                // all KeyEvents returned by KeyCharacterMap.getEvents() have the same
+                // time stamp and the system rejects too old events. Hence, it is
+                // possible for an event to become stale before it is injected if it
+                // takes too long to inject the preceding ones.
+                KeyEvent event = KeyEvent.changeTimeRepeat(event2,
+                        SystemClock.uptimeMillis(), 0);
+                if (!injectEventSync(event)) {
+                    return false;
+                }
+                SystemClock.sleep(keyDelay);
+            }
+        }
+        return true;
+    }
+
+    public boolean sendKey(int keyCode, int metaState) {
+        if (DEBUG) {
+            Log.d(LOG_TAG, "sendKey (" + keyCode + ", " + metaState + ")");
+        }
+
+        final long eventTime = SystemClock.uptimeMillis();
+        KeyEvent downEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
+                keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                InputDevice.SOURCE_KEYBOARD);
+        if (injectEventSync(downEvent)) {
+            KeyEvent upEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP,
+                    keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
+                    InputDevice.SOURCE_KEYBOARD);
+            if(injectEventSync(upEvent)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Rotates right and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationRight() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_270);
+    }
+
+    /**
+     * Rotates left and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationLeft() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_90);
+    }
+
+    /**
+     * Rotates up and also freezes rotation in that position by
+     * disabling the sensors. If you want to un-freeze the rotation
+     * and re-enable the sensors see {@link #unfreezeRotation()}. Note
+     * that doing so may cause the screen contents to rotate
+     * depending on the current physical position of the test device.
+     * @throws RemoteException
+     */
+    public void setRotationNatural() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_0);
+    }
+
+    /**
+     * Disables the sensors and freezes the device rotation at its
+     * current rotation state.
+     * @throws RemoteException
+     */
+    public void freezeRotation() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_FREEZE_CURRENT);
+    }
+
+    /**
+     * Re-enables the sensors and un-freezes the device rotation
+     * allowing its contents to rotate with the device physical rotation.
+     * @throws RemoteException
+     */
+    public void unfreezeRotation() {
+        mUiAutomatorBridge.setRotation(UiAutomation.ROTATION_UNFREEZE);
+    }
+
+    /**
+     * This method simply presses the power button if the screen is OFF else
+     * it does nothing if the screen is already ON.
+     * @return true if the device was asleep else false
+     * @throws RemoteException
+     */
+    public boolean wakeDevice() throws RemoteException {
+        if(!isScreenOn()) {
+            sendKey(KeyEvent.KEYCODE_POWER, 0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This method simply presses the power button if the screen is ON else
+     * it does nothing if the screen is already OFF.
+     * @return true if the device was awake else false
+     * @throws RemoteException
+     */
+    public boolean sleepDevice() throws RemoteException {
+        if(isScreenOn()) {
+            this.sendKey(KeyEvent.KEYCODE_POWER, 0);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Checks the power manager if the screen is ON
+     * @return true if the screen is ON else false
+     * @throws RemoteException
+     */
+    public boolean isScreenOn() throws RemoteException {
+        return mUiAutomatorBridge.isScreenOn();
+    }
+
+    private boolean injectEventSync(InputEvent event) {
+        return mUiAutomatorBridge.injectInputEvent(event, true);
+    }
+
+    private int getPointerAction(int motionEnvent, int index) {
+        return motionEnvent + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
+    }
+
+    /**
+     * Performs a multi-touch gesture
+     *
+     * Takes a series of touch coordinates for at least 2 pointers. Each pointer must have
+     * all of its touch steps defined in an array of {@link PointerCoords}. By having the ability
+     * to specify the touch points along the path of a pointer, the caller is able to specify
+     * complex gestures like circles, irregular shapes etc, where each pointer may take a
+     * different path.
+     *
+     * To create a single point on a pointer's touch path
+     * <code>
+     *       PointerCoords p = new PointerCoords();
+     *       p.x = stepX;
+     *       p.y = stepY;
+     *       p.pressure = 1;
+     *       p.size = 1;
+     * </code>
+     * @param touches each array of {@link PointerCoords} constitute a single pointer's touch path.
+     *        Multiple {@link PointerCoords} arrays constitute multiple pointers, each with its own
+     *        path. Each {@link PointerCoords} in an array constitute a point on a pointer's path.
+     * @return <code>true</code> if all points on all paths are injected successfully, <code>false
+     *        </code>otherwise
+     * @since API Level 18
+     */
+    public boolean performMultiPointerGesture(PointerCoords[] ... touches) {
+        boolean ret = true;
+        if (touches.length < 2) {
+            throw new IllegalArgumentException("Must provide coordinates for at least 2 pointers");
+        }
+
+        // Get the pointer with the max steps to inject.
+        int maxSteps = 0;
+        for (int x = 0; x < touches.length; x++)
+            maxSteps = (maxSteps < touches[x].length) ? touches[x].length : maxSteps;
+
+        // specify the properties for each pointer as finger touch
+        PointerProperties[] properties = new PointerProperties[touches.length];
+        PointerCoords[] pointerCoords = new PointerCoords[touches.length];
+        for (int x = 0; x < touches.length; x++) {
+            PointerProperties prop = new PointerProperties();
+            prop.id = x;
+            prop.toolType = MotionEvent.TOOL_TYPE_FINGER;
+            properties[x] = prop;
+
+            // for each pointer set the first coordinates for touch down
+            pointerCoords[x] = touches[x][0];
+        }
+
+        // Touch down all pointers
+        long downTime = SystemClock.uptimeMillis();
+        MotionEvent event;
+        event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 1,
+                properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+        ret &= injectEventSync(event);
+
+        for (int x = 1; x < touches.length; x++) {
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    getPointerAction(MotionEvent.ACTION_POINTER_DOWN, x), x + 1, properties,
+                    pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+            ret &= injectEventSync(event);
+        }
+
+        // Move all pointers
+        for (int i = 1; i < maxSteps - 1; i++) {
+            // for each pointer
+            for (int x = 0; x < touches.length; x++) {
+                // check if it has coordinates to move
+                if (touches[x].length > i)
+                    pointerCoords[x] = touches[x][i];
+                else
+                    pointerCoords[x] = touches[x][touches[x].length - 1];
+            }
+
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    MotionEvent.ACTION_MOVE, touches.length, properties, pointerCoords, 0, 0, 1, 1,
+                    0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+
+            ret &= injectEventSync(event);
+            SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS);
+        }
+
+        // For each pointer get the last coordinates
+        for (int x = 0; x < touches.length; x++)
+            pointerCoords[x] = touches[x][touches[x].length - 1];
+
+        // touch up
+        for (int x = 1; x < touches.length; x++) {
+            event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(),
+                    getPointerAction(MotionEvent.ACTION_POINTER_UP, x), x + 1, properties,
+                    pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+            ret &= injectEventSync(event);
+        }
+
+        Log.i(LOG_TAG, "x " + pointerCoords[0].x);
+        // first to touch down is last up
+        event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1,
+                properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
+        ret &= injectEventSync(event);
+        return ret;
+    }
+
+    /**
+     * Simulates a short press on the Recent Apps button.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean toggleRecentApps() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_RECENTS);
+    }
+
+    /**
+     * Opens the notification shade
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openNotification() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
+    }
+
+    /**
+     * Opens the quick settings shade
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openQuickSettings() {
+        return mUiAutomatorBridge.performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/QueryController.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/QueryController.java
new file mode 100644
index 0000000..6931528
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/QueryController.java
@@ -0,0 +1,521 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+
+/**
+ * The QueryController main purpose is to translate a {@link UiSelector} selectors to
+ * {@link AccessibilityNodeInfo}. This is all this controller does.
+ */
+class QueryController {
+
+    private static final String LOG_TAG = QueryController.class.getSimpleName();
+
+    private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+    private static final boolean VERBOSE = Log.isLoggable(LOG_TAG, Log.VERBOSE);
+
+    private final UiAutomatorBridge mUiAutomatorBridge;
+
+    private final Object mLock = new Object();
+
+    private String mLastActivityName = null;
+
+    // During a pattern selector search, the recursive pattern search
+    // methods will track their counts and indexes here.
+    private int mPatternCounter = 0;
+    private int mPatternIndexer = 0;
+
+    // These help show each selector's search context as it relates to the previous sub selector
+    // matched. When a compound selector fails, it is hard to tell which part of it is failing.
+    // Seeing how a selector is being parsed and which sub selector failed within a long list
+    // of compound selectors is very helpful.
+    private int mLogIndent = 0;
+    private int mLogParentIndent = 0;
+
+    private String mLastTraversedText = "";
+
+    public QueryController(UiAutomatorBridge bridge) {
+        mUiAutomatorBridge = bridge;
+        bridge.setOnAccessibilityEventListener(new OnAccessibilityEventListener() {
+            @Override
+            public void onAccessibilityEvent(AccessibilityEvent event) {
+                synchronized (mLock) {
+                    switch(event.getEventType()) {
+                        case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+                            // don't trust event.getText(), check for nulls
+                            if (event.getText() != null && event.getText().size() > 0) {
+                                if(event.getText().get(0) != null)
+                                    mLastActivityName = event.getText().get(0).toString();
+                            }
+                           break;
+                        case AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
+                            // don't trust event.getText(), check for nulls
+                            if (event.getText() != null && event.getText().size() > 0)
+                                if(event.getText().get(0) != null)
+                                    mLastTraversedText = event.getText().get(0).toString();
+                            if (DEBUG)
+                                Log.d(LOG_TAG, "Last text selection reported: " +
+                                        mLastTraversedText);
+                            break;
+                    }
+                    mLock.notifyAll();
+                }
+            }
+        });
+    }
+
+    /**
+     * Returns the last text selection reported by accessibility
+     * event TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY. One way to cause
+     * this event is using a DPad arrows to focus on UI elements.
+     */
+    public String getLastTraversedText() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            if (mLastTraversedText.length() > 0) {
+                return mLastTraversedText;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Clears the last text selection value saved from the TYPE_VIEW_TEXT_SELECTION_CHANGED
+     * event
+     */
+    public void clearLastTraversedText() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            mLastTraversedText = "";
+        }
+    }
+
+    private void initializeNewSearch() {
+        mPatternCounter = 0;
+        mPatternIndexer = 0;
+        mLogIndent = 0;
+        mLogParentIndent = 0;
+    }
+
+    /**
+     * Counts the instances of the selector group. The selector must be in the following
+     * format: [container_selector, PATTERN=[INSTANCE=x, PATTERN=[the_pattern]]
+     * where the container_selector is used to find the containment region to search for patterns
+     * and the INSTANCE=x is the instance of the_pattern to return.
+     * @param selector
+     * @return number of pattern matches. Returns 0 for all other cases.
+     */
+    public int getPatternCount(UiSelector selector) {
+        findAccessibilityNodeInfo(selector, true /*counting*/);
+        return mPatternCounter;
+    }
+
+    /**
+     * Main search method for translating By selectors to AccessibilityInfoNodes
+     * @param selector
+     * @return AccessibilityNodeInfo
+     */
+    public AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector) {
+        return findAccessibilityNodeInfo(selector, false);
+    }
+
+    protected AccessibilityNodeInfo findAccessibilityNodeInfo(UiSelector selector,
+            boolean isCounting) {
+        mUiAutomatorBridge.waitForIdle();
+        initializeNewSearch();
+
+        if (DEBUG)
+            Log.d(LOG_TAG, "Searching: " + selector);
+
+        synchronized (mLock) {
+            AccessibilityNodeInfo rootNode = getRootNode();
+            if (rootNode == null) {
+                Log.e(LOG_TAG, "Cannot proceed when root node is null. Aborted search");
+                return null;
+            }
+
+            // Copy so that we don't modify the original's sub selectors
+            UiSelector uiSelector = new UiSelector(selector);
+            return translateCompoundSelector(uiSelector, rootNode, isCounting);
+        }
+    }
+
+    /**
+     * Gets the root node from accessibility and if it fails to get one it will
+     * retry every 250ms for up to 1000ms.
+     * @return null if no root node is obtained
+     */
+    protected AccessibilityNodeInfo getRootNode() {
+        final int maxRetry = 4;
+        final long waitInterval = 250;
+        AccessibilityNodeInfo rootNode = null;
+        for(int x = 0; x < maxRetry; x++) {
+            rootNode = mUiAutomatorBridge.getRootInActiveWindow();
+            if (rootNode != null) {
+                return rootNode;
+            }
+            if(x < maxRetry - 1) {
+                Log.e(LOG_TAG, "Got null root node from accessibility - Retrying...");
+                SystemClock.sleep(waitInterval);
+            }
+        }
+        return rootNode;
+    }
+
+    /**
+     * A compoundSelector encapsulate both Regular and Pattern selectors. The formats follows:
+     * <p/>
+     * regular_selector = By[attributes... CHILD=By[attributes... CHILD=By[....]]]
+     * <br/>
+     * pattern_selector = ...CONTAINER=By[..] PATTERN=By[instance=x PATTERN=[regular_selector]
+     * <br/>
+     * compound_selector = [regular_selector [pattern_selector]]
+     * <p/>
+     * regular_selectors are the most common form of selectors and the search for them
+     * is straightforward. On the other hand pattern_selectors requires search to be
+     * performed as in regular_selector but where regular_selector search returns immediately
+     * upon a successful match, the search for pattern_selector continues until the
+     * requested matched _instance_ of that pattern is matched.
+     * <p/>
+     * Counting UI objects requires using pattern_selectors. The counting search is the same
+     * as a pattern_search however we're not looking to match an instance of the pattern but
+     * rather continuously walking the accessibility node hierarchy while counting matched
+     * patterns, until the end of the tree.
+     * <p/>
+     * If both present, order of parsing begins with CONTAINER followed by PATTERN then the
+     * top most selector is processed as regular_selector within the context of the previous
+     * CONTAINER and its PATTERN information. If neither is present then the top selector is
+     * directly treated as regular_selector. So the presence of a CONTAINER and PATTERN within
+     * a selector simply dictates that the selector matching will be constraint to the sub tree
+     * node where the CONTAINER and its child PATTERN have identified.
+     * @param selector
+     * @param fromNode
+     * @param isCounting
+     * @return AccessibilityNodeInfo
+     */
+    private AccessibilityNodeInfo translateCompoundSelector(UiSelector selector,
+            AccessibilityNodeInfo fromNode, boolean isCounting) {
+
+        // Start translating compound selectors by translating the regular_selector first
+        // The regular_selector is then used as a container for any optional pattern_selectors
+        // that may or may not be specified.
+        if(selector.hasContainerSelector())
+            // nested pattern selectors
+            if(selector.getContainerSelector().hasContainerSelector()) {
+                fromNode = translateCompoundSelector(
+                        selector.getContainerSelector(), fromNode, false);
+                initializeNewSearch();
+            } else
+                fromNode = translateReqularSelector(selector.getContainerSelector(), fromNode);
+        else
+            fromNode = translateReqularSelector(selector, fromNode);
+
+        if(fromNode == null) {
+            if (DEBUG)
+                Log.d(LOG_TAG, "Container selector not found: " + selector.dumpToString(false));
+            return null;
+        }
+
+        if(selector.hasPatternSelector()) {
+            fromNode = translatePatternSelector(selector.getPatternSelector(),
+                    fromNode, isCounting);
+
+            if (isCounting) {
+                Log.i(LOG_TAG, String.format(
+                        "Counted %d instances of: %s", mPatternCounter, selector));
+                return null;
+            } else {
+                if(fromNode == null) {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, "Pattern selector not found: " +
+                                selector.dumpToString(false));
+                    return null;
+                }
+            }
+        }
+
+        // translate any additions to the selector that may have been added by tests
+        // with getChild(By selector) after a container and pattern selectors
+        if(selector.hasContainerSelector() || selector.hasPatternSelector()) {
+            if(selector.hasChildSelector() || selector.hasParentSelector())
+                fromNode = translateReqularSelector(selector, fromNode);
+        }
+
+        if(fromNode == null) {
+            if (DEBUG)
+                Log.d(LOG_TAG, "Object Not Found for selector " + selector);
+            return null;
+        }
+        Log.i(LOG_TAG, String.format("Matched selector: %s <<==>> [%s]", selector, fromNode));
+        return fromNode;
+    }
+
+    /**
+     * Used by the {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     * to translate the regular_selector portion. It has the following format:
+     * <p/>
+     * regular_selector = By[attributes... CHILD=By[attributes... CHILD=By[....]]]<br/>
+     * <p/>
+     * regular_selectors are the most common form of selectors and the search for them
+     * is straightforward. This method will only look for CHILD or PARENT sub selectors.
+     * <p/>
+     * @param selector
+     * @param fromNode
+     * @return AccessibilityNodeInfo if found else null
+     */
+    private AccessibilityNodeInfo translateReqularSelector(UiSelector selector,
+            AccessibilityNodeInfo fromNode) {
+
+        return findNodeRegularRecursive(selector, fromNode, 0);
+    }
+
+    private AccessibilityNodeInfo findNodeRegularRecursive(UiSelector subSelector,
+            AccessibilityNodeInfo fromNode, int index) {
+
+        if (subSelector.isMatchFor(fromNode, index)) {
+            if (DEBUG) {
+                Log.d(LOG_TAG, formatLog(String.format("%s",
+                        subSelector.dumpToString(false))));
+            }
+            if(subSelector.isLeaf()) {
+                return fromNode;
+            }
+            if(subSelector.hasChildSelector()) {
+                mLogIndent++; // next selector
+                subSelector = subSelector.getChildSelector();
+                if(subSelector == null) {
+                    Log.e(LOG_TAG, "Error: A child selector without content");
+                    return null; // there is an implementation fault
+                }
+            } else if(subSelector.hasParentSelector()) {
+                mLogIndent++; // next selector
+                subSelector = subSelector.getParentSelector();
+                if(subSelector == null) {
+                    Log.e(LOG_TAG, "Error: A parent selector without content");
+                    return null; // there is an implementation fault
+                }
+                // the selector requested we start at this level from
+                // the parent node from the one we just matched
+                fromNode = fromNode.getParent();
+                if(fromNode == null)
+                    return null;
+            }
+        }
+
+        int childCount = fromNode.getChildCount();
+        boolean hasNullChild = false;
+        for (int i = 0; i < childCount; i++) {
+            AccessibilityNodeInfo childNode = fromNode.getChild(i);
+            if (childNode == null) {
+                Log.w(LOG_TAG, String.format(
+                        "AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount));
+                if (!hasNullChild) {
+                    Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString()));
+                }
+                hasNullChild = true;
+                continue;
+            }
+            if (!childNode.isVisibleToUser()) {
+                if (VERBOSE)
+                    Log.v(LOG_TAG,
+                            String.format("Skipping invisible child: %s", childNode.toString()));
+                continue;
+            }
+            AccessibilityNodeInfo retNode = findNodeRegularRecursive(subSelector, childNode, i);
+            if (retNode != null) {
+                return retNode;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Used by the {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     * to translate the pattern_selector portion. It has the following format:
+     * <p/>
+     * pattern_selector = ... PATTERN=By[instance=x PATTERN=[regular_selector]]<br/>
+     * <p/>
+     * pattern_selectors requires search to be performed as regular_selector but where
+     * regular_selector search returns immediately upon a successful match, the search for
+     * pattern_selector continues until the requested matched instance of that pattern is
+     * encountered.
+     * <p/>
+     * Counting UI objects requires using pattern_selectors. The counting search is the same
+     * as a pattern_search however we're not looking to match an instance of the pattern but
+     * rather continuously walking the accessibility node hierarchy while counting patterns
+     * until the end of the tree.
+     * @param subSelector
+     * @param fromNode
+     * @param isCounting
+     * @return null of node is not found or if counting mode is true.
+     * See {@link #translateCompoundSelector(UiSelector, AccessibilityNodeInfo, boolean)}
+     */
+    private AccessibilityNodeInfo translatePatternSelector(UiSelector subSelector,
+            AccessibilityNodeInfo fromNode, boolean isCounting) {
+
+        if(subSelector.hasPatternSelector()) {
+            // Since pattern_selectors are also the type of selectors used when counting,
+            // we check if this is a counting run or an indexing run
+            if(isCounting)
+                //since we're counting, we reset the indexer so to terminates the search when
+                // the end of tree is reached. The count will be in mPatternCount
+                mPatternIndexer = -1;
+            else
+                // terminates the search once we match the pattern's instance
+                mPatternIndexer = subSelector.getInstance();
+
+            // A pattern is wrapped in a PATTERN[instance=x PATTERN[the_pattern]]
+            subSelector = subSelector.getPatternSelector();
+            if(subSelector == null) {
+                Log.e(LOG_TAG, "Pattern portion of the selector is null or not defined");
+                return null; // there is an implementation fault
+            }
+            // save the current indent level as parent indent before pattern searches
+            // begin under the current tree position.
+            mLogParentIndent = ++mLogIndent;
+            return findNodePatternRecursive(subSelector, fromNode, 0, subSelector);
+        }
+
+        Log.e(LOG_TAG, "Selector must have a pattern selector defined"); // implementation fault?
+        return null;
+    }
+
+    private AccessibilityNodeInfo findNodePatternRecursive(
+            UiSelector subSelector, AccessibilityNodeInfo fromNode, int index,
+            UiSelector originalPattern) {
+
+        if (subSelector.isMatchFor(fromNode, index)) {
+            if(subSelector.isLeaf()) {
+                if(mPatternIndexer == 0) {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, formatLog(
+                                String.format("%s", subSelector.dumpToString(false))));
+                    return fromNode;
+                } else {
+                    if (DEBUG)
+                        Log.d(LOG_TAG, formatLog(
+                                String.format("%s", subSelector.dumpToString(false))));
+                    mPatternCounter++; //count the pattern matched
+                    mPatternIndexer--; //decrement until zero for the instance requested
+
+                    // At a leaf selector within a group and still not instance matched
+                    // then reset the  selector to continue search from current position
+                    // in the accessibility tree for the next pattern match up until the
+                    // pattern index hits 0.
+                    subSelector = originalPattern;
+                    // starting over with next pattern search so reset to parent level
+                    mLogIndent = mLogParentIndent;
+                }
+            } else {
+                if (DEBUG)
+                    Log.d(LOG_TAG, formatLog(
+                            String.format("%s", subSelector.dumpToString(false))));
+
+                if(subSelector.hasChildSelector()) {
+                    mLogIndent++; // next selector
+                    subSelector = subSelector.getChildSelector();
+                    if(subSelector == null) {
+                        Log.e(LOG_TAG, "Error: A child selector without content");
+                        return null;
+                    }
+                } else if(subSelector.hasParentSelector()) {
+                    mLogIndent++; // next selector
+                    subSelector = subSelector.getParentSelector();
+                    if(subSelector == null) {
+                        Log.e(LOG_TAG, "Error: A parent selector without content");
+                        return null;
+                    }
+                    fromNode = fromNode.getParent();
+                    if(fromNode == null)
+                        return null;
+                }
+            }
+        }
+
+        int childCount = fromNode.getChildCount();
+        boolean hasNullChild = false;
+        for (int i = 0; i < childCount; i++) {
+            AccessibilityNodeInfo childNode = fromNode.getChild(i);
+            if (childNode == null) {
+                Log.w(LOG_TAG, String.format(
+                        "AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount));
+                if (!hasNullChild) {
+                    Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString()));
+                }
+                hasNullChild = true;
+                continue;
+            }
+            if (!childNode.isVisibleToUser()) {
+                if (DEBUG)
+                    Log.d(LOG_TAG,
+                        String.format("Skipping invisible child: %s", childNode.toString()));
+                continue;
+            }
+            AccessibilityNodeInfo retNode = findNodePatternRecursive(
+                    subSelector, childNode, i, originalPattern);
+            if (retNode != null) {
+                return retNode;
+            }
+        }
+        return null;
+    }
+
+    public AccessibilityNodeInfo getAccessibilityRootNode() {
+        return mUiAutomatorBridge.getRootInActiveWindow();
+    }
+
+    /**
+     * Last activity to report accessibility events.
+     * @deprecated The results returned should be considered unreliable
+     * @return String name of activity
+     */
+    @Deprecated
+    public String getCurrentActivityName() {
+        mUiAutomatorBridge.waitForIdle();
+        synchronized (mLock) {
+            return mLastActivityName;
+        }
+    }
+
+    /**
+     * Last package to report accessibility events
+     * @return String name of package
+     */
+    public String getCurrentPackageName() {
+        mUiAutomatorBridge.waitForIdle();
+        AccessibilityNodeInfo rootNode = getRootNode();
+        if (rootNode == null)
+            return null;
+        return rootNode.getPackageName() != null ? rootNode.getPackageName().toString() : null;
+    }
+
+    private String formatLog(String str) {
+        StringBuilder l = new StringBuilder();
+        for(int space = 0; space < mLogIndent; space++)
+            l.append(". . ");
+        if(mLogIndent > 0)
+            l.append(String.format(". . [%d]: %s", mPatternCounter, str));
+        else
+            l.append(String.format(". . [%d]: %s", mPatternCounter, str));
+        return l.toString();
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Tracer.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Tracer.java
new file mode 100644
index 0000000..d574fc0
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/Tracer.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Class that creates traces of the calls to the UiAutomator API and outputs the
+ * traces either to logcat or a logfile. Each public method in the UiAutomator
+ * that needs to be traced should include a call to Tracer.trace in the
+ * beginning. Tracing is turned off by defualt and needs to be enabled
+ * explicitly.
+ * @hide
+ */
+public class Tracer {
+    private static final String UNKNOWN_METHOD_STRING = "(unknown method)";
+    private static final String UIAUTOMATOR_PACKAGE = "com.android.uiautomator.core";
+    private static final int CALLER_LOCATION = 6;
+    private static final int METHOD_TO_TRACE_LOCATION = 5;
+    private static final int MIN_STACK_TRACE_LENGTH = 7;
+
+    /**
+     * Enum that determines where the trace output goes. It can go to either
+     * logcat, log file or both.
+     */
+    public enum Mode {
+        NONE,
+        FILE,
+        LOGCAT,
+        ALL
+    }
+
+    private interface TracerSink {
+        public void log(String message);
+
+        public void close();
+    }
+
+    private class FileSink implements TracerSink {
+        private PrintWriter mOut;
+        private SimpleDateFormat mDateFormat;
+
+        public FileSink(File file) throws FileNotFoundException {
+            mOut = new PrintWriter(file);
+            mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
+        }
+
+        public void log(String message) {
+            mOut.printf("%s %s\n", mDateFormat.format(new Date()), message);
+        }
+
+        public void close() {
+            mOut.close();
+        }
+    }
+
+    private class LogcatSink implements TracerSink {
+
+        private static final String LOGCAT_TAG = "UiAutomatorTrace";
+
+        public void log(String message) {
+            Log.i(LOGCAT_TAG, message);
+        }
+
+        public void close() {
+            // nothing is needed
+        }
+    }
+
+    private Mode mCurrentMode = Mode.NONE;
+    private List<TracerSink> mSinks = new ArrayList<TracerSink>();
+    private File mOutputFile;
+
+    private static Tracer mInstance = null;
+
+    /**
+     * Returns a reference to an instance of the tracer. Useful to set the
+     * parameters before the trace is collected.
+     *
+     * @return
+     */
+    public static Tracer getInstance() {
+        if (mInstance == null) {
+            mInstance = new Tracer();
+        }
+        return mInstance;
+    }
+
+    /**
+     * Sets where the trace output will go. Can be either be logcat or a file or
+     * both. Setting this to NONE will turn off tracing.
+     *
+     * @param mode
+     */
+    public void setOutputMode(Mode mode) {
+        closeSinks();
+        mCurrentMode = mode;
+        try {
+            switch (mode) {
+                case FILE:
+                    if (mOutputFile == null) {
+                        throw new IllegalArgumentException("Please provide a filename before " +
+                                "attempting write trace to a file");
+                    }
+                    mSinks.add(new FileSink(mOutputFile));
+                    break;
+                case LOGCAT:
+                    mSinks.add(new LogcatSink());
+                    break;
+                case ALL:
+                    mSinks.add(new LogcatSink());
+                    if (mOutputFile == null) {
+                        throw new IllegalArgumentException("Please provide a filename before " +
+                                "attempting write trace to a file");
+                    }
+                    mSinks.add(new FileSink(mOutputFile));
+                    break;
+                default:
+                    break;
+            }
+        } catch (FileNotFoundException e) {
+            Log.w("Tracer", "Could not open log file: " + e.getMessage());
+        }
+    }
+
+    private void closeSinks() {
+        for (TracerSink sink : mSinks) {
+            sink.close();
+        }
+        mSinks.clear();
+    }
+
+    /**
+     * Sets the name of the log file where tracing output will be written if the
+     * tracer is set to write to a file.
+     *
+     * @param filename name of the log file.
+     */
+    public void setOutputFilename(String filename) {
+        mOutputFile = new File(filename);
+    }
+
+    private void doTrace(Object[] arguments) {
+        if (mCurrentMode == Mode.NONE) {
+            return;
+        }
+
+        String caller = getCaller();
+        if (caller == null) {
+            return;
+        }
+
+        log(String.format("%s (%s)", caller, join(", ", arguments)));
+    }
+
+    private void log(String message) {
+        for (TracerSink sink : mSinks) {
+            sink.log(message);
+        }
+    }
+
+    /**
+     * Queries whether the tracing is enabled.
+     * @return true if tracing is enabled, false otherwise.
+     */
+    public boolean isTracingEnabled() {
+        return mCurrentMode != Mode.NONE;
+    }
+
+    /**
+     * Public methods in the UiAutomator should call this function to generate a
+     * trace. The trace will include the method thats is being called, it's
+     * arguments and where in the user's code the method is called from. If a
+     * public method is called internally from UIAutomator then this will not
+     * output a trace entry. Only calls from outise the UiAutomator package will
+     * produce output.
+     *
+     * Special note about array arguments. You can safely pass arrays of reference types
+     * to this function. Like String[] or Integer[]. The trace function will print their
+     * contents by calling toString() on each of the elements. This will not work for
+     * array of primitive types like int[] or float[]. Before passing them to this function
+     * convert them to arrays of reference types manually. Example: convert int[] to Integer[].
+     *
+     * @param arguments arguments of the method being traced.
+     */
+    public static void trace(Object... arguments) {
+        Tracer.getInstance().doTrace(arguments);
+    }
+
+    private static String join(String separator, Object[] strings) {
+        if (strings.length == 0)
+            return "";
+
+        StringBuilder builder = new StringBuilder(objectToString(strings[0]));
+        for (int i = 1; i < strings.length; i++) {
+            builder.append(separator);
+            builder.append(objectToString(strings[i]));
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Special toString method to handle arrays. If the argument is a normal object then this will
+     * return normal output of obj.toString(). If the argument is an array this will return a
+     * string representation of the elements of the array.
+     *
+     * This method will not work for arrays of primitive types. Arrays of primitive types are
+     * expected to be converted manually by the caller. If the array is not converter then
+     * this function will only output "[...]" instead of the contents of the array.
+     *
+     * @param obj object to convert to a string
+     * @return String representation of the object.
+     */
+    private static String objectToString(Object obj) {
+        if (obj.getClass().isArray()) {
+            if (obj instanceof Object[]) {
+                return Arrays.deepToString((Object[])obj);
+            } else {
+                return "[...]";
+            }
+        } else {
+            return obj.toString();
+        }
+    }
+
+    /**
+     * This method outputs which UiAutomator method was called and where in the
+     * user code it was called from. If it can't deside which method is called
+     * it will output "(unknown method)". If the method was called from inside
+     * the UiAutomator then it returns null.
+     *
+     * @return name of the method called and where it was called from. Null if
+     *         method was called from inside UiAutomator.
+     */
+    private static String getCaller() {
+        StackTraceElement stackTrace[] = Thread.currentThread().getStackTrace();
+        if (stackTrace.length < MIN_STACK_TRACE_LENGTH) {
+            return UNKNOWN_METHOD_STRING;
+        }
+
+        StackTraceElement caller = stackTrace[METHOD_TO_TRACE_LOCATION];
+        StackTraceElement previousCaller = stackTrace[CALLER_LOCATION];
+
+        if (previousCaller.getClassName().startsWith(UIAUTOMATOR_PACKAGE)) {
+            return null;
+        }
+
+        int indexOfDot = caller.getClassName().lastIndexOf('.');
+        if (indexOfDot < 0) {
+            indexOfDot = 0;
+        }
+
+        if (indexOfDot + 1 >= caller.getClassName().length()) {
+            return UNKNOWN_METHOD_STRING;
+        }
+
+        String shortClassName = caller.getClassName().substring(indexOfDot + 1);
+        return String.format("%s.%s from %s() at %s:%d", shortClassName, caller.getMethodName(),
+                previousCaller.getMethodName(), previousCaller.getFileName(),
+                previousCaller.getLineNumber());
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
new file mode 100644
index 0000000..bc5bc8e
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiAutomatorBridge.java
@@ -0,0 +1,143 @@
+package com.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.app.UiAutomation.OnAccessibilityEventListener;
+import android.graphics.Bitmap;
+import android.util.Log;
+import android.view.Display;
+import android.view.InputEvent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * @hide
+ */
+public abstract class UiAutomatorBridge {
+
+    private static final String LOG_TAG = UiAutomatorBridge.class.getSimpleName();
+
+   /**
+    * This value has the greatest bearing on the appearance of test execution speeds.
+    * This value is used as the minimum time to wait before considering the UI idle after
+    * each action.
+    */
+    private static final long QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500;//ms
+
+   /**
+    * This is the maximum time the automation will wait for the UI to go idle. Execution
+    * will resume normally anyway. This is to prevent waiting forever on display updates
+    * that may be related to spinning wheels or progress updates of sorts etc...
+    */
+    private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
+
+    private final UiAutomation mUiAutomation;
+
+    private final InteractionController mInteractionController;
+
+    private final QueryController mQueryController;
+
+    UiAutomatorBridge(UiAutomation uiAutomation) {
+        mUiAutomation = uiAutomation;
+        mInteractionController = new InteractionController(this);
+        mQueryController = new QueryController(this);
+    }
+
+    InteractionController getInteractionController() {
+        return mInteractionController;
+    }
+
+    QueryController getQueryController() {
+        return mQueryController;
+    }
+
+    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
+        mUiAutomation.setOnAccessibilityEventListener(listener);
+    }
+
+    public AccessibilityNodeInfo getRootInActiveWindow() {
+        return mUiAutomation.getRootInActiveWindow();
+    }
+
+    public boolean injectInputEvent(InputEvent event, boolean sync) {
+        return mUiAutomation.injectInputEvent(event, sync);
+    }
+
+    public boolean setRotation(int rotation) {
+        return mUiAutomation.setRotation(rotation);
+    }
+
+    public void setCompressedLayoutHierarchy(boolean compressed) {
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        if (compressed)
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        else
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    public abstract int getRotation();
+
+    public abstract boolean isScreenOn();
+
+    public void waitForIdle() {
+        waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
+    }
+
+    public void waitForIdle(long timeout) {
+        try {
+            mUiAutomation.waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);
+        } catch (TimeoutException te) {
+            Log.w(LOG_TAG, "Could not detect idle state.", te);
+        }
+    }
+
+    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
+            AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
+        return mUiAutomation.executeAndWaitForEvent(command,
+                filter, timeoutMillis);
+    }
+
+    public boolean takeScreenshot(File storePath, int quality) {
+        Bitmap screenshot = mUiAutomation.takeScreenshot();
+        if (screenshot == null) {
+            return false;
+        }
+        BufferedOutputStream bos = null;
+        try {
+            bos = new BufferedOutputStream(new FileOutputStream(storePath));
+            if (bos != null) {
+                screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos);
+                bos.flush();
+            }
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
+            return false;
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException ioe) {
+                    /* ignore */
+                }
+            }
+            screenshot.recycle();
+        }
+        return true;
+    }
+
+    public boolean performGlobalAction(int action) {
+        return mUiAutomation.performGlobalAction(action);
+    }
+
+    public abstract Display getDefaultDisplay();
+
+    public abstract long getSystemLongPressTime();
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiCollection.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiCollection.java
new file mode 100644
index 0000000..e15beb2
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiCollection.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+/**
+ * Used to enumerate a container's UI elements for the purpose of counting,
+ * or targeting a sub elements by a child's text or description.
+ * @since API Level 16
+ */
+public class UiCollection extends UiObject {
+
+    /**
+     * Constructs an instance as described by the selector
+     *
+     * @param selector
+     * @since API Level 16
+     */
+    public UiCollection(UiSelector selector) {
+        super(selector);
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that has content-description text.
+     * The returned UiObject will point at the <code>childPattern</code> instance that matched the
+     * search and not at the identifying child element that matched the content description.</p>
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param text String of the identifying child contents of of the <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByDescription(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        if (text != null) {
+            int count = getChildCount(childPattern);
+            for (int x = 0; x < count; x++) {
+                UiObject row = getChildByInstance(childPattern, x);
+                String nodeDesc = row.getContentDescription();
+                if(nodeDesc != null && nodeDesc.contains(text)) {
+                    return row;
+                }
+                UiObject item = row.getChild(new UiSelector().descriptionContains(text));
+                if (item.exists()) {
+                    return row;
+                }
+            }
+        }
+        throw new UiObjectNotFoundException("for description= \"" + text + "\"");
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that is at the <code>instance</code>
+     * specified. The operation is performed only on the visible items and no scrolling is performed
+     * in this case.
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param instance int the desired matched instance of this <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @since API Level 16
+     */
+    public UiObject getChildByInstance(UiSelector childPattern, int instance)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, instance);
+        UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
+                UiSelector.patternBuilder(childPattern).instance(instance));
+        return new UiObject(patternSelector);
+    }
+
+    /**
+     * Searches for child UI element within the constraints of this UiCollection {@link UiSelector}
+     * selector.
+     *
+     * It looks for any child matching the <code>childPattern</code> argument that has
+     * a child UI element anywhere within its sub hierarchy that has text attribute =
+     * <code>text</code>. The returned UiObject will point at the <code>childPattern</code>
+     * instance that matched the search and not at the identifying child element that matched the
+     * text attribute.</p>
+     *
+     * @param childPattern {@link UiSelector} selector of the child pattern to match and return
+     * @param text String of the identifying child contents of of the <code>childPattern</code>
+     * @return {@link UiObject} pointing at and instance of <code>childPattern</code>
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByText(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        if (text != null) {
+            int count = getChildCount(childPattern);
+            for (int x = 0; x < count; x++) {
+                UiObject row = getChildByInstance(childPattern, x);
+                String nodeText = row.getText();
+                if(text.equals(nodeText)) {
+                    return row;
+                }
+                UiObject item = row.getChild(new UiSelector().text(text));
+                if (item.exists()) {
+                    return row;
+                }
+            }
+        }
+        throw new UiObjectNotFoundException("for text= \"" + text + "\"");
+    }
+
+    /**
+     * Counts child UI element instances matching the <code>childPattern</code>
+     * argument. The method returns the number of matching UI elements that are
+     * currently visible.  The count does not include items of a scrollable list
+     * that are off-screen.
+     *
+     * @param childPattern a {@link UiSelector} that represents the matching child UI
+     * elements to count
+     * @return the number of matched childPattern under the current {@link UiCollection}
+     * @since API Level 16
+     */
+    public int getChildCount(UiSelector childPattern) {
+        Tracer.trace(childPattern);
+        UiSelector patternSelector =
+                UiSelector.patternBuilder(getSelector(), UiSelector.patternBuilder(childPattern));
+        return getQueryController().getPatternCount(patternSelector);
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java
new file mode 100644
index 0000000..a930eb4
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiDevice.java
@@ -0,0 +1,851 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.app.UiAutomation;
+import android.app.UiAutomation.AccessibilityEventFilter;
+import android.graphics.Point;
+import android.os.Build;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.KeyEvent;
+import android.view.Surface;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * UiDevice provides access to state information about the device.
+ * You can also use this class to simulate user actions on the device,
+ * such as pressing the d-pad or pressing the Home and Menu buttons.
+ * @since API Level 16
+ */
+public class UiDevice {
+    private static final String LOG_TAG = UiDevice.class.getSimpleName();
+
+    // Sometimes HOME and BACK key presses will generate no events if already on
+    // home page or there is nothing to go back to, Set low timeouts.
+    private static final long KEY_PRESS_EVENT_TIMEOUT = 1 * 1000;
+
+    // store for registered UiWatchers
+    private final HashMap<String, UiWatcher> mWatchers = new HashMap<String, UiWatcher>();
+    private final List<String> mWatchersTriggers = new ArrayList<String>();
+
+    // remember if we're executing in the context of a UiWatcher
+    private boolean mInWatcherContext = false;
+
+    // provides access the {@link QueryController} and {@link InteractionController}
+    private UiAutomatorBridge mUiAutomationBridge;
+
+    // reference to self
+    private static UiDevice sDevice;
+
+    private UiDevice() {
+        /* hide constructor */
+    }
+
+    /**
+     * @hide
+     */
+    public void initialize(UiAutomatorBridge uiAutomatorBridge) {
+        mUiAutomationBridge = uiAutomatorBridge;
+    }
+
+    boolean isInWatcherContext() {
+        return mInWatcherContext;
+    }
+
+    /**
+     * Provides access the {@link QueryController} and {@link InteractionController}
+     * @return {@link ShellUiAutomatorBridge}
+     */
+    UiAutomatorBridge getAutomatorBridge() {
+        if (mUiAutomationBridge == null) {
+            throw new RuntimeException("UiDevice not initialized");
+        }
+        return mUiAutomationBridge;
+    }
+
+    /**
+     * Enables or disables layout hierarchy compression.
+     *
+     * If compression is enabled, the layout hierarchy derived from the Acessibility
+     * framework will only contain nodes that are important for uiautomator
+     * testing. Any unnecessary surrounding layout nodes that make viewing
+     * and searching the hierarchy inefficient are removed.
+     *
+     * @param compressed true to enable compression; else, false to disable
+     * @since API Level 18
+     */
+    public void setCompressedLayoutHeirarchy(boolean compressed) {
+        getAutomatorBridge().setCompressedLayoutHierarchy(compressed);
+    }
+
+    /**
+     * Retrieves a singleton instance of UiDevice
+     *
+     * @return UiDevice instance
+     * @since API Level 16
+     */
+    public static UiDevice getInstance() {
+        if (sDevice == null) {
+            sDevice = new UiDevice();
+        }
+        return sDevice;
+    }
+
+    /**
+     * Returns the display size in dp (device-independent pixel)
+     *
+     * The returned display size is adjusted per screen rotation. Also this will return the actual
+     * size of the screen, rather than adjusted per system decorations (like status bar).
+     *
+     * @return a Point containing the display size in dp
+     */
+    public Point getDisplaySizeDp() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getRealSize(p);
+        DisplayMetrics metrics = new DisplayMetrics();
+        display.getRealMetrics(metrics);
+        float dpx = p.x / metrics.density;
+        float dpy = p.y / metrics.density;
+        p.x = Math.round(dpx);
+        p.y = Math.round(dpy);
+        return p;
+    }
+
+    /**
+     * Retrieves the product name of the device.
+     *
+     * This method provides information on what type of device the test is running on. This value is
+     * the same as returned by invoking #adb shell getprop ro.product.name.
+     *
+     * @return product name of the device
+     * @since API Level 17
+     */
+    public String getProductName() {
+        Tracer.trace();
+        return Build.PRODUCT;
+    }
+
+    /**
+     * Retrieves the text from the last UI traversal event received.
+     *
+     * You can use this method to read the contents in a WebView container
+     * because the accessibility framework fires events
+     * as each text is highlighted. You can write a test to perform
+     * directional arrow presses to focus on different elements inside a WebView,
+     * and call this method to get the text from each traversed element.
+     * If you are testing a view container that can return a reference to a
+     * Document Object Model (DOM) object, your test should use the view's
+     * DOM instead.
+     *
+     * @return text of the last traversal event, else return an empty string
+     * @since API Level 16
+     */
+    public String getLastTraversedText() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getLastTraversedText();
+    }
+
+    /**
+     * Clears the text from the last UI traversal event.
+     * See {@link #getLastTraversedText()}.
+     * @since API Level 16
+     */
+    public void clearLastTraversedText() {
+        Tracer.trace();
+        getAutomatorBridge().getQueryController().clearLastTraversedText();
+    }
+
+    /**
+     * Simulates a short press on the MENU button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressMenu() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the BACK button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressBack() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the HOME button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressHome() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent(
+                KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
+                KEY_PRESS_EVENT_TIMEOUT);
+    }
+
+    /**
+     * Simulates a short press on the SEARCH button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressSearch() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_SEARCH);
+    }
+
+    /**
+     * Simulates a short press on the CENTER button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadCenter() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
+    }
+
+    /**
+     * Simulates a short press on the DOWN button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadDown() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN);
+    }
+
+    /**
+     * Simulates a short press on the UP button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadUp() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_UP);
+    }
+
+    /**
+     * Simulates a short press on the LEFT button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadLeft() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT);
+    }
+
+    /**
+     * Simulates a short press on the RIGHT button.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDPadRight() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT);
+    }
+
+    /**
+     * Simulates a short press on the DELETE key.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressDelete() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_DEL);
+    }
+
+    /**
+     * Simulates a short press on the ENTER key.
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressEnter() {
+        Tracer.trace();
+        return pressKeyCode(KeyEvent.KEYCODE_ENTER);
+    }
+
+    /**
+     * Simulates a short press using a key code.
+     *
+     * See {@link KeyEvent}
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressKeyCode(int keyCode) {
+        Tracer.trace(keyCode);
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, 0);
+    }
+
+    /**
+     * Simulates a short press using a key code.
+     *
+     * See {@link KeyEvent}.
+     * @param keyCode the key code of the event.
+     * @param metaState an integer in which each bit set to 1 represents a pressed meta key
+     * @return true if successful, else return false
+     * @since API Level 16
+     */
+    public boolean pressKeyCode(int keyCode, int metaState) {
+        Tracer.trace(keyCode, metaState);
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().sendKey(keyCode, metaState);
+    }
+
+    /**
+     * Simulates a short press on the Recent Apps button.
+     *
+     * @return true if successful, else return false
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public boolean pressRecentApps() throws RemoteException {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().toggleRecentApps();
+    }
+
+    /**
+     * Opens the notification shade.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openNotification() {
+        Tracer.trace();
+        waitForIdle();
+        return  getAutomatorBridge().getInteractionController().openNotification();
+    }
+
+    /**
+     * Opens the Quick Settings shade.
+     *
+     * @return true if successful, else return false
+     * @since API Level 18
+     */
+    public boolean openQuickSettings() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getInteractionController().openQuickSettings();
+    }
+
+    /**
+     * Gets the width of the display, in pixels. The width and height details
+     * are reported based on the current orientation of the display.
+     * @return width in pixels or zero on failure
+     * @since API Level 16
+     */
+    public int getDisplayWidth() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getSize(p);
+        return p.x;
+    }
+
+    /**
+     * Gets the height of the display, in pixels. The size is adjusted based
+     * on the current orientation of the display.
+     * @return height in pixels or zero on failure
+     * @since API Level 16
+     */
+    public int getDisplayHeight() {
+        Tracer.trace();
+        Display display = getAutomatorBridge().getDefaultDisplay();
+        Point p = new Point();
+        display.getSize(p);
+        return p.y;
+    }
+
+    /**
+     * Perform a click at arbitrary coordinates specified by the user
+     *
+     * @param x coordinate
+     * @param y coordinate
+     * @return true if the click succeeded else false
+     * @since API Level 16
+     */
+    public boolean click(int x, int y) {
+        Tracer.trace(x, y);
+        if (x >= getDisplayWidth() || y >= getDisplayHeight()) {
+            return (false);
+        }
+        return getAutomatorBridge().getInteractionController().clickNoSync(x, y);
+    }
+
+    /**
+     * Performs a swipe from one coordinate to another using the number of steps
+     * to determine smoothness and speed. Each step execution is throttled to 5ms
+     * per step. So for a 100 steps, the swipe will take about 1/2 second to complete.
+     *
+     * @param startX
+     * @param startY
+     * @param endX
+     * @param endY
+     * @param steps is the number of move steps sent to the system
+     * @return false if the operation fails or the coordinates are invalid
+     * @since API Level 16
+     */
+    public boolean swipe(int startX, int startY, int endX, int endY, int steps) {
+        Tracer.trace(startX, startY, endX, endY, steps);
+        return getAutomatorBridge().getInteractionController()
+                .swipe(startX, startY, endX, endY, steps);
+    }
+
+    /**
+     * Performs a swipe from one coordinate to another coordinate. You can control
+     * the smoothness and speed of the swipe by specifying the number of steps.
+     * Each step execution is throttled to 5 milliseconds per step, so for a 100
+     * steps, the swipe will take around 0.5 seconds to complete.
+     *
+     * @param startX X-axis value for the starting coordinate
+     * @param startY Y-axis value for the starting coordinate
+     * @param endX X-axis value for the ending coordinate
+     * @param endY Y-axis value for the ending coordinate
+     * @param steps is the number of steps for the swipe action
+     * @return true if swipe is performed, false if the operation fails 
+     * or the coordinates are invalid
+     * @since API Level 18
+     */
+    public boolean drag(int startX, int startY, int endX, int endY, int steps) {
+        Tracer.trace(startX, startY, endX, endY, steps);
+        return getAutomatorBridge().getInteractionController()
+                .swipe(startX, startY, endX, endY, steps, true);
+    }
+
+    /**
+     * Performs a swipe between points in the Point array. Each step execution is throttled
+     * to 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to complete
+     *
+     * @param segments is Point array containing at least one Point object
+     * @param segmentSteps steps to inject between two Points
+     * @return true on success
+     * @since API Level 16
+     */
+    public boolean swipe(Point[] segments, int segmentSteps) {
+        Tracer.trace(segments, segmentSteps);
+        return getAutomatorBridge().getInteractionController().swipe(segments, segmentSteps);
+    }
+
+    /**
+     * Waits for the current application to idle.
+     * Default wait timeout is 10 seconds
+     * @since API Level 16
+     */
+    public void waitForIdle() {
+        Tracer.trace();
+        waitForIdle(Configurator.getInstance().getWaitForIdleTimeout());
+    }
+
+    /**
+     * Waits for the current application to idle.
+     * @param timeout in milliseconds
+     * @since API Level 16
+     */
+    public void waitForIdle(long timeout) {
+        Tracer.trace(timeout);
+        getAutomatorBridge().waitForIdle(timeout);
+    }
+
+    /**
+     * Retrieves the last activity to report accessibility events.
+     * @deprecated The results returned should be considered unreliable
+     * @return String name of activity
+     * @since API Level 16
+     */
+    @Deprecated
+    public String getCurrentActivityName() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getCurrentActivityName();
+    }
+
+    /**
+     * Retrieves the name of the last package to report accessibility events.
+     * @return String name of package
+     * @since API Level 16
+     */
+    public String getCurrentPackageName() {
+        Tracer.trace();
+        return getAutomatorBridge().getQueryController().getCurrentPackageName();
+    }
+
+    /**
+     * Registers a {@link UiWatcher} to run automatically when the testing framework is unable to
+     * find a match using a {@link UiSelector}. See {@link #runWatchers()}
+     *
+     * @param name to register the UiWatcher
+     * @param watcher {@link UiWatcher}
+     * @since API Level 16
+     */
+    public void registerWatcher(String name, UiWatcher watcher) {
+        Tracer.trace(name, watcher);
+        if (mInWatcherContext) {
+            throw new IllegalStateException("Cannot register new watcher from within another");
+        }
+        mWatchers.put(name, watcher);
+    }
+
+    /**
+     * Removes a previously registered {@link UiWatcher}.
+     *
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @param name used to register the UiWatcher
+     * @since API Level 16
+     */
+    public void removeWatcher(String name) {
+        Tracer.trace(name);
+        if (mInWatcherContext) {
+            throw new IllegalStateException("Cannot remove a watcher from within another");
+        }
+        mWatchers.remove(name);
+    }
+
+    /**
+     * This method forces all registered watchers to run.
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @since API Level 16
+     */
+    public void runWatchers() {
+        Tracer.trace();
+        if (mInWatcherContext) {
+            return;
+        }
+
+        for (String watcherName : mWatchers.keySet()) {
+            UiWatcher watcher = mWatchers.get(watcherName);
+            if (watcher != null) {
+                try {
+                    mInWatcherContext = true;
+                    if (watcher.checkForCondition()) {
+                        setWatcherTriggered(watcherName);
+                    }
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e);
+                } finally {
+                    mInWatcherContext = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Resets a {@link UiWatcher} that has been triggered.
+     * If a UiWatcher runs and its {@link UiWatcher#checkForCondition()} call
+     * returned <code>true</code>, then the UiWatcher is considered triggered.
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * @since API Level 16
+     */
+    public void resetWatcherTriggers() {
+        Tracer.trace();
+        mWatchersTriggers.clear();
+    }
+
+    /**
+     * Checks if a specific registered  {@link UiWatcher} has triggered.
+     * See {@link #registerWatcher(String, UiWatcher)}. If a UiWatcher runs and its
+     * {@link UiWatcher#checkForCondition()} call returned <code>true</code>, then
+     * the UiWatcher is considered triggered. This is helpful if a watcher is detecting errors
+     * from ANR or crash dialogs and the test needs to know if a UiWatcher has been triggered.
+     *
+     * @param watcherName
+     * @return true if triggered else false
+     * @since API Level 16
+     */
+    public boolean hasWatcherTriggered(String watcherName) {
+        Tracer.trace(watcherName);
+        return mWatchersTriggers.contains(watcherName);
+    }
+
+    /**
+     * Checks if any registered {@link UiWatcher} have triggered.
+     *
+     * See {@link #registerWatcher(String, UiWatcher)}
+     * See {@link #hasWatcherTriggered(String)}
+     * @since API Level 16
+     */
+    public boolean hasAnyWatcherTriggered() {
+        Tracer.trace();
+        return mWatchersTriggers.size() > 0;
+    }
+
+    /**
+     * Used internally by this class to set a {@link UiWatcher} state as triggered.
+     * @param watcherName
+     */
+    private void setWatcherTriggered(String watcherName) {
+        Tracer.trace(watcherName);
+        if (!hasWatcherTriggered(watcherName)) {
+            mWatchersTriggers.add(watcherName);
+        }
+    }
+
+    /**
+     * Check if the device is in its natural orientation. This is determined by checking if the
+     * orientation is at 0 or 180 degrees.
+     * @return true if it is in natural orientation
+     * @since API Level 17
+     */
+    public boolean isNaturalOrientation() {
+        Tracer.trace();
+        waitForIdle();
+        int ret = getAutomatorBridge().getRotation();
+        return ret == UiAutomation.ROTATION_FREEZE_0 ||
+                ret == UiAutomation.ROTATION_FREEZE_180;
+    }
+
+    /**
+     * Returns the current rotation of the display, as defined in {@link Surface}
+     * @since API Level 17
+     */
+    public int getDisplayRotation() {
+        Tracer.trace();
+        waitForIdle();
+        return getAutomatorBridge().getRotation();
+    }
+
+    /**
+     * Disables the sensors and freezes the device rotation at its
+     * current rotation state.
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void freezeRotation() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().freezeRotation();
+    }
+
+    /**
+     * Re-enables the sensors and un-freezes the device rotation allowing its contents
+     * to rotate with the device physical rotation. During a test execution, it is best to
+     * keep the device frozen in a specific orientation until the test case execution has completed.
+     * @throws RemoteException
+     */
+    public void unfreezeRotation() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().unfreezeRotation();
+    }
+
+    /**
+     * Simulates orienting the device to the left and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationLeft() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationLeft();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * Simulates orienting the device to the right and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationRight() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationRight();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * Simulates orienting the device into its natural orientation and also freezes rotation
+     * by disabling the sensors.
+     *
+     * If you want to un-freeze the rotation and re-enable the sensors
+     * see {@link #unfreezeRotation()}.
+     * @throws RemoteException
+     * @since API Level 17
+     */
+    public void setOrientationNatural() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().setRotationNatural();
+        waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
+    }
+
+    /**
+     * This method simulates pressing the power button if the screen is OFF else
+     * it does nothing if the screen is already ON.
+     *
+     * If the screen was OFF and it just got turned ON, this method will insert a 500ms delay
+     * to allow the device time to wake up and accept input.
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void wakeUp() throws RemoteException {
+        Tracer.trace();
+        if(getAutomatorBridge().getInteractionController().wakeDevice()) {
+            // sync delay to allow the window manager to start accepting input
+            // after the device is awakened.
+            SystemClock.sleep(500);
+        }
+    }
+
+    /**
+     * Checks the power manager if the screen is ON.
+     *
+     * @return true if the screen is ON else false
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public boolean isScreenOn() throws RemoteException {
+        Tracer.trace();
+        return getAutomatorBridge().getInteractionController().isScreenOn();
+    }
+
+    /**
+     * This method simply presses the power button if the screen is ON else
+     * it does nothing if the screen is already OFF.
+     *
+     * @throws RemoteException
+     * @since API Level 16
+     */
+    public void sleep() throws RemoteException {
+        Tracer.trace();
+        getAutomatorBridge().getInteractionController().sleepDevice();
+    }
+
+    /**
+     * Helper method used for debugging to dump the current window's layout hierarchy.
+     * The file root location is /data/local/tmp
+     *
+     * @param fileName
+     * @since API Level 16
+     */
+    public void dumpWindowHierarchy(String fileName) {
+        Tracer.trace(fileName);
+        AccessibilityNodeInfo root =
+                getAutomatorBridge().getQueryController().getAccessibilityRootNode();
+        if(root != null) {
+            Display display = getAutomatorBridge().getDefaultDisplay();
+            Point size = new Point();
+            display.getSize(size);
+            AccessibilityNodeInfoDumper.dumpWindowToFile(root,
+                    new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName),
+                    display.getRotation(), size.x, size.y);
+        }
+    }
+
+    /**
+     * Waits for a window content update event to occur.
+     *
+     * If a package name for the window is specified, but the current window
+     * does not have the same package name, the function returns immediately.
+     *
+     * @param packageName the specified window package name (can be <code>null</code>).
+     *        If <code>null</code>, a window update from any front-end window will end the wait
+     * @param timeout the timeout for the wait
+     *
+     * @return true if a window update occurred, false if timeout has elapsed or if the current
+     *         window does not have the specified package name
+     * @since API Level 16
+     */
+    public boolean waitForWindowUpdate(final String packageName, long timeout) {
+        Tracer.trace(packageName, timeout);
+        if (packageName != null) {
+            if (!packageName.equals(getCurrentPackageName())) {
+                return false;
+            }
+        }
+        Runnable emptyRunnable = new Runnable() {
+            @Override
+            public void run() {
+            }
+        };
+        AccessibilityEventFilter checkWindowUpdate = new AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent t) {
+                if (t.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
+                    return packageName == null || packageName.equals(t.getPackageName());
+                }
+                return false;
+            }
+        };
+        try {
+            getAutomatorBridge().executeCommandAndWaitForAccessibilityEvent(
+                    emptyRunnable, checkWindowUpdate, timeout);
+        } catch (TimeoutException e) {
+            return false;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "waitForWindowUpdate: general exception from bridge", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Take a screenshot of current window and store it as PNG
+     *
+     * Default scale of 1.0f (original size) and 90% quality is used
+     * The screenshot is adjusted per screen rotation
+     *
+     * @param storePath where the PNG should be written to
+     * @return true if screen shot is created successfully, false otherwise
+     * @since API Level 17
+     */
+    public boolean takeScreenshot(File storePath) {
+        Tracer.trace(storePath);
+        return takeScreenshot(storePath, 1.0f, 90);
+    }
+
+    /**
+     * Take a screenshot of current window and store it as PNG
+     *
+     * The screenshot is adjusted per screen rotation
+     *
+     * @param storePath where the PNG should be written to
+     * @param scale scale the screenshot down if needed; 1.0f for original size
+     * @param quality quality of the PNG compression; range: 0-100
+     * @return true if screen shot is created successfully, false otherwise
+     * @since API Level 17
+     */
+    public boolean takeScreenshot(File storePath, float scale, int quality) {
+        Tracer.trace(storePath, scale, quality);
+        return getAutomatorBridge().takeScreenshot(storePath, quality);
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java
new file mode 100644
index 0000000..4bb99cd
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObject.java
@@ -0,0 +1,1083 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * A UiObject is a representation of a view. It is not in any way directly bound to a
+ * view as an object reference. A UiObject contains information to help it
+ * locate a matching view at runtime based on the {@link UiSelector} properties specified in
+ * its constructor. Once you create an instance of a UiObject, it can
+ * be reused for different views that match the selector criteria.
+ * @since API Level 16
+ */
+public class UiObject {
+    private static final String LOG_TAG = UiObject.class.getSimpleName();
+    /**
+     * @since API Level 16
+     * @deprecated use {@link Configurator#setWaitForSelectorTimeout(long)}
+     **/
+    @Deprecated
+    protected static final long WAIT_FOR_SELECTOR_TIMEOUT = 10 * 1000;
+    /**
+     * @since API Level 16
+     **/
+    protected static final long WAIT_FOR_SELECTOR_POLL = 1000;
+    // set a default timeout to 5.5s, since ANR threshold is 5s
+    /**
+     * @since API Level 16
+     **/
+    protected static final long WAIT_FOR_WINDOW_TMEOUT = 5500;
+    /**
+     * @since API Level 16
+     **/
+    protected static final int SWIPE_MARGIN_LIMIT = 5;
+    /**
+     * @since API Level 17
+     * @deprecated use {@link Configurator#setScrollAcknowledgmentTimeout(long)}
+     **/
+    @Deprecated
+    protected static final long WAIT_FOR_EVENT_TMEOUT = 3 * 1000;
+    /**
+     * @since API Level 18
+     **/
+    protected static final int FINGER_TOUCH_HALF_WIDTH = 20;
+
+    private final UiSelector mSelector;
+
+    private final Configurator mConfig = Configurator.getInstance();
+
+    /**
+     * Constructs a UiObject to represent a view that matches the specified
+     * selector criteria.
+     * @param selector
+     * @since API Level 16
+     */
+    public UiObject(UiSelector selector) {
+        mSelector = selector;
+    }
+
+    /**
+     * Debugging helper. A test can dump the properties of a selector as a string
+     * to its logs if needed. <code>getSelector().toString();</code>
+     *
+     * @return {@link UiSelector}
+     * @since API Level 16
+     */
+    public final UiSelector getSelector() {
+        Tracer.trace();
+        return new UiSelector(mSelector);
+    }
+
+    /**
+     * Retrieves the {@link QueryController} to translate a {@link UiSelector} selector
+     * into an {@link AccessibilityNodeInfo}.
+     *
+     * @return {@link QueryController}
+     */
+    QueryController getQueryController() {
+        return UiDevice.getInstance().getAutomatorBridge().getQueryController();
+    }
+
+    /**
+     * Retrieves the {@link InteractionController} to perform finger actions such as tapping,
+     * swiping, or entering text.
+     *
+     * @return {@link InteractionController}
+     */
+    InteractionController getInteractionController() {
+        return UiDevice.getInstance().getAutomatorBridge().getInteractionController();
+    }
+
+    /**
+     * Creates a new UiObject for a child view that is under the present UiObject.
+     *
+     * @param selector for child view to match
+     * @return a new UiObject representing the child view
+     * @since API Level 16
+     */
+    public UiObject getChild(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        return new UiObject(getSelector().childSelector(selector));
+    }
+
+    /**
+     * Creates a new UiObject for a sibling view or a child of the sibling view, 
+     * relative to the present UiObject.
+     *
+     * @param selector for a sibling view or children of the sibling view
+     * @return a new UiObject representing the matched view
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getFromParent(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        return new UiObject(getSelector().fromParent(selector));
+    }
+
+    /**
+     * Counts the child views immediately under the present UiObject.
+     *
+     * @return the count of child views.
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public int getChildCount() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.getChildCount();
+    }
+
+    /**
+     * Finds a matching UI element in the accessibility hierarchy, by
+     * using the selector for this UiObject.
+     *
+     * @param timeout in milliseconds
+     * @return AccessibilityNodeInfo if found else null
+     * @since API Level 16
+     */
+    protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout) {
+        AccessibilityNodeInfo node = null;
+        long startMills = SystemClock.uptimeMillis();
+        long currentMills = 0;
+        while (currentMills <= timeout) {
+            node = getQueryController().findAccessibilityNodeInfo(getSelector());
+            if (node != null) {
+                break;
+            } else {
+                // does nothing if we're reentering another runWatchers()
+                UiDevice.getInstance().runWatchers();
+            }
+            currentMills = SystemClock.uptimeMillis() - startMills;
+            if(timeout > 0) {
+                SystemClock.sleep(WAIT_FOR_SELECTOR_POLL);
+            }
+        }
+        return node;
+    }
+
+    /**
+     * Drags this object to a destination UiObject.
+     * The number of steps specified in your input parameter can influence the
+     * drag speed, and varying speeds may impact the results. Consider
+     * evaluating different speeds when using this method in your tests.
+     *
+     * @param destObj the destination UiObject.
+     * @param steps usually 40 steps. You can increase or decrease the steps to change the speed.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean dragTo(UiObject destObj, int steps) throws UiObjectNotFoundException {
+        Rect srcRect = getVisibleBounds();
+        Rect dstRect = destObj.getVisibleBounds();
+        return getInteractionController().swipe(srcRect.centerX(), srcRect.centerY(),
+                dstRect.centerX(), dstRect.centerY(), steps, true);
+    }
+
+    /**
+     * Drags this object to arbitrary coordinates.
+     * The number of steps specified in your input parameter can influence the
+     * drag speed, and varying speeds may impact the results. Consider
+     * evaluating different speeds when using this method in your tests.
+     *
+     * @param destX the X-axis coordinate.
+     * @param destY the Y-axis coordinate.
+     * @param steps usually 40 steps. You can increase or decrease the steps to change the speed.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean dragTo(int destX, int destY, int steps) throws UiObjectNotFoundException {
+        Rect srcRect = getVisibleBounds();
+        return getInteractionController().swipe(srcRect.centerX(), srcRect.centerY(), destX, destY,
+                steps, true);
+    }
+
+    /**
+     * Performs the swipe up action on the UiObject. 
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true of successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeUp(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.height() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.centerX(),
+                rect.bottom - SWIPE_MARGIN_LIMIT, rect.centerX(), rect.top + SWIPE_MARGIN_LIMIT,
+                steps);
+    }
+
+    /**
+     * Performs the swipe down action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeDown(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.height() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.centerX(),
+                rect.top + SWIPE_MARGIN_LIMIT, rect.centerX(),
+                rect.bottom - SWIPE_MARGIN_LIMIT, steps);
+    }
+
+    /**
+     * Performs the swipe left action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeLeft(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.width() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.right - SWIPE_MARGIN_LIMIT,
+                rect.centerY(), rect.left + SWIPE_MARGIN_LIMIT, rect.centerY(), steps);
+    }
+
+    /**
+     * Performs the swipe right action on the UiObject. 
+     * The swipe gesture can be performed over any surface. The targeted
+     * UI element does not need to be scrollable.
+     * See also:
+     * <ul>
+     * <li>{@link UiScrollable#scrollToBeginning(int)}</li>
+     * <li>{@link UiScrollable#scrollToEnd(int)}</li>
+     * <li>{@link UiScrollable#scrollBackward()}</li>
+     * <li>{@link UiScrollable#scrollForward()}</li>
+     * </ul>
+     *
+     * @param steps indicates the number of injected move steps into the system. Steps are
+     * injected about 5ms apart. So a 100 steps may take about 1/2 second to complete.
+     * @return true if successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean swipeRight(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Rect rect = getVisibleBounds();
+        if(rect.width() <= SWIPE_MARGIN_LIMIT * 2)
+            return false; // too small to swipe
+        return getInteractionController().swipe(rect.left + SWIPE_MARGIN_LIMIT,
+                rect.centerY(), rect.right - SWIPE_MARGIN_LIMIT, rect.centerY(), steps);
+    }
+
+    /**
+     * Finds the visible bounds of a partially visible UI element
+     *
+     * @param node
+     * @return null if node is null, else a Rect containing visible bounds
+     */
+    private Rect getVisibleBounds(AccessibilityNodeInfo node) {
+        if (node == null) {
+            return null;
+        }
+
+        // targeted node's bounds
+        int w = UiDevice.getInstance().getDisplayWidth();
+        int h = UiDevice.getInstance().getDisplayHeight();
+        Rect nodeRect = AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(node, w, h);
+
+        // is the targeted node within a scrollable container?
+        AccessibilityNodeInfo scrollableParentNode = getScrollableParent(node);
+        if(scrollableParentNode == null) {
+            // nothing to adjust for so return the node's Rect as is
+            return nodeRect;
+        }
+
+        // Scrollable parent's visible bounds
+        Rect parentRect = AccessibilityNodeInfoHelper
+                .getVisibleBoundsInScreen(scrollableParentNode, w, h);
+        // adjust for partial clipping of targeted by parent node if required
+        nodeRect.intersect(parentRect);
+        return nodeRect;
+    }
+
+    /**
+     * Walks up the layout hierarchy to find a scrollable parent. A scrollable parent
+     * indicates that this node might be in a container where it is partially
+     * visible due to scrolling. In this case, its clickable center might not be visible and
+     * the click coordinates should be adjusted.
+     *
+     * @param node
+     * @return The accessibility node info.
+     */
+    private AccessibilityNodeInfo getScrollableParent(AccessibilityNodeInfo node) {
+        AccessibilityNodeInfo parent = node;
+        while(parent != null) {
+            parent = parent.getParent();
+            if (parent != null && parent.isScrollable()) {
+                return parent;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Performs a click at the center of the visible bounds of the UI element represented
+     * by this UiObject.
+     *
+     * @return true id successful else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean click() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickAndSync(rect.centerX(), rect.centerY(),
+                mConfig.getActionAcknowledgmentTimeout());
+    }
+
+    /**
+     * Waits for window transitions that would typically take longer than the
+     * usual default timeouts.
+     * See {@link #clickAndWaitForNewWindow(long)}
+     *
+     * @return true if the event was triggered, else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickAndWaitForNewWindow() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return clickAndWaitForNewWindow(WAIT_FOR_WINDOW_TMEOUT);
+    }
+
+    /**
+     * Performs a click at the center of the visible bounds of the UI element represented
+     * by this UiObject and waits for window transitions.
+     *
+     * This method differ from {@link UiObject#click()} only in that this method waits for a
+     * a new window transition as a result of the click. Some examples of a window transition:
+     * <li>launching a new activity</li>
+     * <li>bringing up a pop-up menu</li>
+     * <li>bringing up a dialog</li>
+     *
+     * @param timeout timeout before giving up on waiting for a new window
+     * @return true if the event was triggered, else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickAndWaitForNewWindow(long timeout) throws UiObjectNotFoundException {
+        Tracer.trace(timeout);
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickAndWaitForNewWindow(rect.centerX(), rect.centerY(),
+                mConfig.getActionAcknowledgmentTimeout());
+    }
+
+    /**
+     * Clicks the top and left corner of the UI element
+     *
+     * @return true on success
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickTopLeft() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickNoSync(rect.left + 5, rect.top + 5);
+    }
+
+    /**
+     * Long clicks bottom and right corner of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClickBottomRight() throws UiObjectNotFoundException  {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.right - 5, rect.bottom - 5);
+    }
+
+    /**
+     * Clicks the bottom and right corner of the UI element
+     *
+     * @return true on success
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean clickBottomRight() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().clickNoSync(rect.right - 5, rect.bottom - 5);
+    }
+
+    /**
+     * Long clicks the center of the visible bounds of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClick() throws UiObjectNotFoundException  {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.centerX(), rect.centerY());
+    }
+
+    /**
+     * Long clicks on the top and left corner of the UI element
+     *
+     * @return true if operation was successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean longClickTopLeft() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        return getInteractionController().longTapNoSync(rect.left + 5, rect.top + 5);
+    }
+
+    /**
+     * Reads the <code>text</code> property of the UI element
+     *
+     * @return text value of the current node represented by this UiObject
+     * @throws UiObjectNotFoundException if no match could be found
+     * @since API Level 16
+     */
+    public String getText() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        String retVal = safeStringReturn(node.getText());
+        Log.d(LOG_TAG, String.format("getText() = %s", retVal));
+        return retVal;
+    }
+
+    /**
+     * Retrieves the <code>className</code> property of the UI element.
+     *
+     * @return class name of the current node represented by this UiObject
+     * @throws UiObjectNotFoundException if no match was found
+     * @since API Level 18
+     */
+    public String getClassName() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        String retVal = safeStringReturn(node.getClassName());
+        Log.d(LOG_TAG, String.format("getClassName() = %s", retVal));
+        return retVal;
+    }
+
+    /**
+     * Reads the <code>content_desc</code> property of the UI element
+     *
+     * @return value of node attribute "content_desc"
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public String getContentDescription() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return safeStringReturn(node.getContentDescription());
+    }
+
+    /**
+     * Sets the text in an editable field, after clearing the field's content.
+     *
+     * The {@link UiSelector} selector of this object must reference a UI element that is editable.
+     *
+     * When you call this method, the method first simulates a {@link #click()} on
+     * editable field to set focus. The method then clears the field's contents
+     * and injects your specified text into the field.
+     *
+     * If you want to capture the original contents of the field, call {@link #getText()} first.
+     * You can then modify the text and use this method to update the field.
+     *
+     * @param text string to set
+     * @return true if operation is successful
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean setText(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        clearTextField();
+        return getInteractionController().sendText(text);
+    }
+
+    /**
+     * Clears the existing text contents in an editable field.
+     *
+     * The {@link UiSelector} of this object must reference a UI element that is editable.
+     *
+     * When you call this method, the method first sets focus at the start edge of the field.
+     * The method then simulates a long-press to select the existing text, and deletes the
+     * selected text.
+     *
+     * If a "Select-All" option is displayed, the method will automatically attempt to use it
+     * to ensure full text selection.
+     *
+     * Note that it is possible that not all the text in the field is selected; for example,
+     * if the text contains separators such as spaces, slashes, at symbol etc.
+     * Also, not all editable fields support the long-press functionality.
+     *
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public void clearTextField() throws UiObjectNotFoundException {
+        Tracer.trace();
+        // long click left + center
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = getVisibleBounds(node);
+        getInteractionController().longTapNoSync(rect.left + 20, rect.centerY());
+        // check if the edit menu is open
+        UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
+        if(selectAll.waitForExists(50))
+            selectAll.click();
+        // wait for the selection
+        SystemClock.sleep(250);
+        // delete it
+        getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
+    }
+
+    /**
+     * Check if the UI element's <code>checked</code> property is currently true
+     *
+     * @return true if it is else false
+     * @since API Level 16
+     */
+    public boolean isChecked() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isChecked();
+    }
+
+    /**
+     * Checks if the UI element's <code>selected</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isSelected() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isSelected();
+    }
+
+    /**
+     * Checks if the UI element's <code>checkable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isCheckable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isCheckable();
+    }
+
+    /**
+     * Checks if the UI element's <code>enabled</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isEnabled() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isEnabled();
+    }
+
+    /**
+     * Checks if the UI element's <code>clickable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isClickable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isClickable();
+    }
+
+    /**
+     * Check if the UI element's <code>focused</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isFocused() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isFocused();
+    }
+
+    /**
+     * Check if the UI element's <code>focusable</code> property is currently true.
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isFocusable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isFocusable();
+    }
+
+    /**
+     * Check if the view's <code>scrollable</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isScrollable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isScrollable();
+    }
+
+    /**
+     * Check if the view's <code>long-clickable</code> property is currently true
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public boolean isLongClickable() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return node.isLongClickable();
+    }
+
+    /**
+     * Reads the view's <code>package</code> property
+     *
+     * @return true if it is else false
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public String getPackageName() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return safeStringReturn(node.getPackageName());
+    }
+
+    /**
+     * Returns the visible bounds of the view.
+     *
+     * If a portion of the view is visible, only the bounds of the visible portion are
+     * reported.
+     *
+     * @return Rect
+     * @throws UiObjectNotFoundException
+     * @see {@link #getBounds()}
+     * @since API Level 17
+     */
+    public Rect getVisibleBounds() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        return getVisibleBounds(node);
+    }
+
+    /**
+     * Returns the view's <code>bounds</code> property. See {@link #getVisibleBounds()}
+     *
+     * @return Rect
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public Rect getBounds() throws UiObjectNotFoundException {
+        Tracer.trace();
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect nodeRect = new Rect();
+        node.getBoundsInScreen(nodeRect);
+
+        return nodeRect;
+    }
+
+    /**
+     * Waits a specified length of time for a view to become visible.
+     *
+     * This method waits until the view becomes visible on the display, or
+     * until the timeout has elapsed. You can use this method in situations where
+     * the content that you want to select is not immediately displayed.
+     *
+     * @param timeout the amount of time to wait (in milliseconds)
+     * @return true if the view is displayed, else false if timeout elapsed while waiting
+     * @since API Level 16
+     */
+    public boolean waitForExists(long timeout) {
+        Tracer.trace(timeout);
+        if(findAccessibilityNodeInfo(timeout) != null) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Waits a specified length of time for a view to become undetectable.
+     *
+     * This method waits until a view is no longer matchable, or until the
+     * timeout has elapsed.
+     *
+     * A view becomes undetectable when the {@link UiSelector} of the object is
+     * unable to find a match because the element has either changed its state or is no
+     * longer displayed.
+     *
+     * You can use this method when attempting to wait for some long operation
+     * to compete, such as downloading a large file or connecting to a remote server.
+     *
+     * @param timeout time to wait (in milliseconds)
+     * @return true if the element is gone before timeout elapsed, else false if timeout elapsed
+     * but a matching element is still found.
+     * @since API Level 16
+     */
+    public boolean waitUntilGone(long timeout) {
+        Tracer.trace(timeout);
+        long startMills = SystemClock.uptimeMillis();
+        long currentMills = 0;
+        while (currentMills <= timeout) {
+            if(findAccessibilityNodeInfo(0) == null)
+                return true;
+            currentMills = SystemClock.uptimeMillis() - startMills;
+            if(timeout > 0)
+                SystemClock.sleep(WAIT_FOR_SELECTOR_POLL);
+        }
+        return false;
+    }
+
+    /**
+     * Check if view exists.
+     *
+     * This methods performs a {@link #waitForExists(long)} with zero timeout. This
+     * basically returns immediately whether the view represented by this UiObject
+     * exists or not. If you need to wait longer for this view, then see
+     * {@link #waitForExists(long)}.
+     *
+     * @return true if the view represented by this UiObject does exist
+     * @since API Level 16
+     */
+    public boolean exists() {
+        Tracer.trace();
+        return waitForExists(0);
+    }
+
+    private String safeStringReturn(CharSequence cs) {
+        if(cs == null)
+            return "";
+        return cs.toString();
+    }
+
+    /**
+     * Performs a two-pointer gesture, where each pointer moves diagonally
+     * opposite across the other, from the center out towards the edges of the
+     * this UiObject.
+     * @param percent percentage of the object's diagonal length for the pinch gesture
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean pinchOut(int percent, int steps) throws UiObjectNotFoundException {
+        // make value between 1 and 100
+        percent = (percent < 0) ? 1 : (percent > 100) ? 100 : percent;
+        float percentage = percent / 100f;
+
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+
+        Rect rect = getVisibleBounds(node);
+        if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2)
+            throw new IllegalStateException("Object width is too small for operation");
+
+        // start from the same point at the center of the control
+        Point startPoint1 = new Point(rect.centerX() - FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+        Point startPoint2 = new Point(rect.centerX() + FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+
+        // End at the top-left and bottom-right corners of the control
+        Point endPoint1 = new Point(rect.centerX() - (int)((rect.width()/2) * percentage),
+                rect.centerY());
+        Point endPoint2 = new Point(rect.centerX() + (int)((rect.width()/2) * percentage),
+                rect.centerY());
+
+        return performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
+    }
+
+    /**
+     * Performs a two-pointer gesture, where each pointer moves diagonally
+     * toward the other, from the edges to the center of this UiObject .
+     * @param percent percentage of the object's diagonal length for the pinch gesture
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @throws UiObjectNotFoundException
+     * @since API Level 18
+     */
+    public boolean pinchIn(int percent, int steps) throws UiObjectNotFoundException {
+        // make value between 1 and 100
+        percent = (percent < 0) ? 0 : (percent > 100) ? 100 : percent;
+        float percentage = percent / 100f;
+
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+
+        Rect rect = getVisibleBounds(node);
+        if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2)
+            throw new IllegalStateException("Object width is too small for operation");
+
+        Point startPoint1 = new Point(rect.centerX() - (int)((rect.width()/2) * percentage),
+                rect.centerY());
+        Point startPoint2 = new Point(rect.centerX() + (int)((rect.width()/2) * percentage),
+                rect.centerY());
+
+        Point endPoint1 = new Point(rect.centerX() - FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+        Point endPoint2 = new Point(rect.centerX() + FINGER_TOUCH_HALF_WIDTH, rect.centerY());
+
+        return performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
+    }
+
+    /**
+     * Generates a two-pointer gesture with arbitrary starting and ending points.
+     *
+     * @param startPoint1 start point of pointer 1
+     * @param startPoint2 start point of pointer 2
+     * @param endPoint1 end point of pointer 1
+     * @param endPoint2 end point of pointer 2
+     * @param steps the number of steps for the gesture. Steps are injected 
+     * about 5 milliseconds apart, so 100 steps may take around 0.5 seconds to complete.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @since API Level 18
+     */
+    public boolean performTwoPointerGesture(Point startPoint1, Point startPoint2, Point endPoint1,
+            Point endPoint2, int steps) {
+
+        // avoid a divide by zero
+        if(steps == 0)
+            steps = 1;
+
+        final float stepX1 = (endPoint1.x - startPoint1.x) / steps;
+        final float stepY1 = (endPoint1.y - startPoint1.y) / steps;
+        final float stepX2 = (endPoint2.x - startPoint2.x) / steps;
+        final float stepY2 = (endPoint2.y - startPoint2.y) / steps;
+
+        int eventX1, eventY1, eventX2, eventY2;
+        eventX1 = startPoint1.x;
+        eventY1 = startPoint1.y;
+        eventX2 = startPoint2.x;
+        eventY2 = startPoint2.y;
+
+        // allocate for steps plus first down and last up
+        PointerCoords[] points1 = new PointerCoords[steps + 2];
+        PointerCoords[] points2 = new PointerCoords[steps + 2];
+
+        // Include the first and last touch downs in the arrays of steps
+        for (int i = 0; i < steps + 1; i++) {
+            PointerCoords p1 = new PointerCoords();
+            p1.x = eventX1;
+            p1.y = eventY1;
+            p1.pressure = 1;
+            p1.size = 1;
+            points1[i] = p1;
+
+            PointerCoords p2 = new PointerCoords();
+            p2.x = eventX2;
+            p2.y = eventY2;
+            p2.pressure = 1;
+            p2.size = 1;
+            points2[i] = p2;
+
+            eventX1 += stepX1;
+            eventY1 += stepY1;
+            eventX2 += stepX2;
+            eventY2 += stepY2;
+        }
+
+        // ending pointers coordinates
+        PointerCoords p1 = new PointerCoords();
+        p1.x = endPoint1.x;
+        p1.y = endPoint1.y;
+        p1.pressure = 1;
+        p1.size = 1;
+        points1[steps + 1] = p1;
+
+        PointerCoords p2 = new PointerCoords();
+        p2.x = endPoint2.x;
+        p2.y = endPoint2.y;
+        p2.pressure = 1;
+        p2.size = 1;
+        points2[steps + 1] = p2;
+
+        return performMultiPointerGesture(points1, points2);
+    }
+
+    /**
+     * Performs a multi-touch gesture. You must specify touch coordinates for
+     * at least 2 pointers. Each pointer must have all of its touch steps
+     * defined in an array of {@link PointerCoords}. You can use this method to
+     * specify complex gestures, like circles and irregular shapes, where each
+     * pointer may take a different path.
+     *
+     * To create a single point on a pointer's touch path:
+     * <code>
+     *       PointerCoords p = new PointerCoords();
+     *       p.x = stepX;
+     *       p.y = stepY;
+     *       p.pressure = 1;
+     *       p.size = 1;
+     * </code>
+     * @param touches represents the pointers' paths. Each {@link PointerCoords}
+     * array represents a different pointer. Each {@link PointerCoords} in an
+     * array element represents a touch point on a pointer's path.
+     * @return <code>true</code> if all touch events for this gesture are injected successfully,
+     *         <code>false</code> otherwise
+     * @since API Level 18
+     */
+    public boolean performMultiPointerGesture(PointerCoords[] ...touches) {
+        return getInteractionController().performMultiPointerGesture(touches);
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java
new file mode 100644
index 0000000..fc0891b
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiObjectNotFoundException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+/**
+ * Generated in test runs when a {@link UiSelector} selector could not be matched
+ * to any UI element displayed.
+ * @since API Level 16
+ */
+public class UiObjectNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(String detailMessage, Throwable throwable) {
+        super(detailMessage, throwable);
+    }
+
+    /**
+     * @since API Level 16
+     **/
+    public UiObjectNotFoundException(Throwable throwable) {
+        super(throwable);
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiScrollable.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiScrollable.java
new file mode 100644
index 0000000..a8d20c3
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiScrollable.java
@@ -0,0 +1,665 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * UiScrollable is a {@link UiCollection} and provides support for searching
+ * for items in scrollable layout elements. This class can be used with
+ * horizontally or vertically scrollable controls.
+ * @since API Level 16
+ */
+public class UiScrollable extends UiCollection {
+    private static final String LOG_TAG = UiScrollable.class.getSimpleName();
+
+    // More steps slows the swipe and prevents contents from being flung too far
+    private static final int SCROLL_STEPS = 55;
+
+    private static final int FLING_STEPS = 5;
+
+    // Restrict a swipe's starting and ending points inside a 10% margin of the target
+    private static final double DEFAULT_SWIPE_DEADZONE_PCT = 0.1;
+
+    // Limits the number of swipes/scrolls performed during a search
+    private static int mMaxSearchSwipes = 30;
+
+    // Used in ScrollForward() and ScrollBackward() to determine swipe direction
+    private boolean mIsVerticalList = true;
+
+    private double mSwipeDeadZonePercentage = DEFAULT_SWIPE_DEADZONE_PCT;
+
+    /**
+     * Constructor.
+     *
+     * @param container a {@link UiSelector} selector to identify the scrollable
+     *     layout element.
+     * @since API Level 16
+     */
+    public UiScrollable(UiSelector container) {
+        // wrap the container selector with container so that QueryController can handle
+        // this type of enumeration search accordingly
+        super(container);
+    }
+
+    /**
+     * Set the direction of swipes to be vertical when performing scroll actions.
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setAsVerticalList() {
+        Tracer.trace();
+        mIsVerticalList = true;
+        return this;
+    }
+
+    /**
+     * Set the direction of swipes to be horizontal when performing scroll actions.
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setAsHorizontalList() {
+        Tracer.trace();
+        mIsVerticalList = false;
+        return this;
+    }
+
+    /**
+     * Used privately when performing swipe searches to decide if an element has become
+     * visible or not.
+     *
+     * @param selector
+     * @return true if found else false
+     * @since API Level 16
+     */
+    protected boolean exists(UiSelector selector) {
+        if(getQueryController().findAccessibilityNodeInfo(selector) != null) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container.
+     * The search first looks for a child element that matches the selector
+     * you provided, then looks for the content-description in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the content-description). By default, this method performs a
+     * scroll search.
+     * See {@link #getChildByDescription(UiSelector, String, boolean)}
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param text Content-description to find in the children of 
+     * the <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByDescription(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        return getChildByDescription(childPattern, text, true);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container.
+     * The search first looks for a child element that matches the selector
+     * you provided, then looks for the content-description in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the content-description).
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param text Content-description to find in the children of 
+     * the <code>childPattern</code> match (may be a partial match)
+     * @param allowScrollSearch set to true if scrolling is allowed
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByDescription(UiSelector childPattern, String text,
+            boolean allowScrollSearch) throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text, allowScrollSearch);
+        if (text != null) {
+            if (allowScrollSearch) {
+                scrollIntoView(new UiSelector().descriptionContains(text));
+            }
+            return super.getChildByDescription(childPattern, text);
+        }
+        throw new UiObjectNotFoundException("for description= \"" + text + "\"");
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container that
+     * matches the selector you provided. The search is performed without
+     * scrolling and only on visible elements.
+     *
+     * @param childPattern {@link UiSelector} for a child in a scollable layout element
+     * @param instance int number representing the occurance of 
+     * a <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByInstance(UiSelector childPattern, int instance)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, instance);
+        UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
+                UiSelector.patternBuilder(childPattern).instance(instance));
+        return new UiObject(patternSelector);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable
+     * container. The search first looks for a child element that matches the
+     * selector you provided, then looks for the text in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the text). By default, this method performs a
+     * scroll search.
+     * See {@link #getChildByText(UiSelector, String, boolean)}
+     *
+     * @param childPattern {@link UiSelector} selector for a child in a scrollable layout element
+     * @param text String to find in the children of the <code>childPattern</code> match
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    @Override
+    public UiObject getChildByText(UiSelector childPattern, String text)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text);
+        return getChildByText(childPattern, text, true);
+    }
+
+    /**
+     * Searches for a child element in the present scrollable container. The
+     * search first looks for a child element that matches the
+     * selector you provided, then looks for the text in its children elements.
+     * If both search conditions are fulfilled, the method returns a {@ link UiObject}
+     * representing the element matching the selector (not the child element in its
+     * subhierarchy containing the text).
+     *
+     * @param childPattern {@link UiSelector} selector for a child in a scrollable layout element
+     * @param text String to find in the children of the <code>childPattern</code> match
+     * @param allowScrollSearch set to true if scrolling is allowed
+     * @return {@link UiObject} representing the child element that matches the search conditions
+     * @throws UiObjectNotFoundException
+     * @since API Level 16
+     */
+    public UiObject getChildByText(UiSelector childPattern, String text, boolean allowScrollSearch)
+            throws UiObjectNotFoundException {
+        Tracer.trace(childPattern, text, allowScrollSearch);
+        if (text != null) {
+            if (allowScrollSearch) {
+                scrollIntoView(new UiSelector().text(text));
+            }
+            return super.getChildByText(childPattern, text);
+        }
+        throw new UiObjectNotFoundException("for text= \"" + text + "\"");
+    }
+
+    /**
+     * Performs a forward scroll action on the scrollable layout element until
+     * the content-description is found, or until swipe attempts have been exhausted.
+     * See {@link #setMaxSearchSwipes(int)}
+     *
+     * @param text content-description to find within the contents of this scrollable layout element.
+     * @return true if item is found; else, false
+     * @since API Level 16
+     */
+    public boolean scrollDescriptionIntoView(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        return scrollIntoView(new UiSelector().description(text));
+    }
+
+    /**
+     * Perform a forward scroll action to move through the scrollable layout element until
+     * a visible item that matches the {@link UiObject} is found.
+     *
+     * @param obj {@link UiObject}
+     * @return true if the item was found and now is in view else false
+     * @since API Level 16
+     */
+    public boolean scrollIntoView(UiObject obj) throws UiObjectNotFoundException {
+        Tracer.trace(obj.getSelector());
+        return scrollIntoView(obj.getSelector());
+    }
+
+    /**
+     * Perform a scroll forward action to move through the scrollable layout 
+     * element until a visible item that matches the selector is found.
+     *
+     * See {@link #scrollDescriptionIntoView(String)} and {@link #scrollTextIntoView(String)}.
+     *
+     * @param selector {@link UiSelector} selector
+     * @return true if the item was found and now is in view; else, false
+     * @since API Level 16
+     */
+    public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException {
+        Tracer.trace(selector);
+        // if we happen to be on top of the text we want then return here
+        UiSelector childSelector = getSelector().childSelector(selector);
+        if (exists(childSelector)) {
+            return (true);
+        } else {
+            // we will need to reset the search from the beginning to start search
+            scrollToBeginning(mMaxSearchSwipes);
+            if (exists(childSelector)) {
+                return (true);
+            }
+            for (int x = 0; x < mMaxSearchSwipes; x++) {
+                boolean scrolled = scrollForward();
+                if(exists(childSelector)) {
+                    return true;
+                }
+                if (!scrolled) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Scrolls forward until the UiObject is fully visible in the scrollable container.
+     * Use this method to make sure that the child item's edges are not offscreen.
+     *
+     * @param childObject {@link UiObject} representing the child element
+     * @return true if the child element is already fully visible, or 
+     * if the method scrolled successfully until the child became fully visible; 
+     * otherwise, false if the attempt to scroll failed.
+     * @throws UiObjectNotFoundException
+     * @hide
+     */
+    public boolean ensureFullyVisible(UiObject childObject) throws UiObjectNotFoundException {
+        Rect actual = childObject.getBounds();
+        Rect visible = childObject.getVisibleBounds();
+        if (visible.width() * visible.height() == actual.width() * actual.height()) {
+            // area match, item fully visible
+            return true;
+        }
+        boolean shouldSwipeForward = false;
+        if (mIsVerticalList) {
+            // if list is vertical, matching top edge implies obscured bottom edge
+            // so we need to scroll list forward
+            shouldSwipeForward = actual.top == visible.top;
+        } else {
+            // if list is horizontal, matching left edge implies obscured right edge,
+            // so we need to scroll list forward
+            shouldSwipeForward = actual.left == visible.left;
+        }
+        if (mIsVerticalList) {
+            if (shouldSwipeForward) {
+                return swipeUp(10);
+            } else {
+                return swipeDown(10);
+            }
+        } else {
+            if (shouldSwipeForward) {
+                return swipeLeft(10);
+            } else {
+                return swipeRight(10);
+            }
+        }
+    }
+
+    /**
+     * Performs a forward scroll action on the scrollable layout element until
+     * the text you provided is visible, or until swipe attempts have been exhausted.
+     * See {@link #setMaxSearchSwipes(int)}
+     *
+     * @param text test to look for
+     * @return true if item is found; else, false
+     * @since API Level 16
+     */
+    public boolean scrollTextIntoView(String text) throws UiObjectNotFoundException {
+        Tracer.trace(text);
+        return scrollIntoView(new UiSelector().text(text));
+    }
+
+    /**
+     * Sets the maximum number of scrolls allowed when performing a
+     * scroll action in search of a child element.
+     * See {@link #getChildByDescription(UiSelector, String)} and
+     * {@link #getChildByText(UiSelector, String)}.
+     *
+     * @param swipes the number of search swipes to perform until giving up
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setMaxSearchSwipes(int swipes) {
+        Tracer.trace(swipes);
+        mMaxSearchSwipes = swipes;
+        return this;
+    }
+
+    /**
+     * Gets the maximum number of scrolls allowed when performing a
+     * scroll action in search of a child element.
+     * See {@link #getChildByDescription(UiSelector, String)} and
+     * {@link #getChildByText(UiSelector, String)}.
+     *
+     * @return max the number of search swipes to perform until giving up
+     * @since API Level 16
+     */
+    public int getMaxSearchSwipes() {
+        Tracer.trace();
+        return mMaxSearchSwipes;
+    }
+
+    /**
+     * Performs a forward fling with the default number of fling steps (5).
+     * If the swipe direction is set to vertical, then the swipes will be
+     * performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean flingForward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollForward(FLING_STEPS);
+    }
+
+    /**
+     * Performs a forward scroll with the default number of scroll steps (55).
+     * If the swipe direction is set to vertical,
+     * then the swipes will be performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollForward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollForward(SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a forward scroll. If the swipe direction is set to vertical,
+     * then the swipes will be performed from bottom to top. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * right to left. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps number of steps. Use this to control the speed of the scroll action
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollForward(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Log.d(LOG_TAG, "scrollForward() on selector = " + getSelector());
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
+        if(node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = new Rect();
+        node.getBoundsInScreen(rect);
+
+        int downX = 0;
+        int downY = 0;
+        int upX = 0;
+        int upY = 0;
+
+        // scrolling is by default assumed vertically unless the object is explicitly
+        // set otherwise by setAsHorizontalContainer()
+        if(mIsVerticalList) {
+            int swipeAreaAdjust = (int)(rect.height() * getSwipeDeadZonePercentage());
+            // scroll vertically: swipe down -> up
+            downX = rect.centerX();
+            downY = rect.bottom - swipeAreaAdjust;
+            upX = rect.centerX();
+            upY = rect.top + swipeAreaAdjust;
+        } else {
+            int swipeAreaAdjust = (int)(rect.width() * getSwipeDeadZonePercentage());
+            // scroll horizontally: swipe right -> left
+            // TODO: Assuming device is not in right to left language
+            downX = rect.right - swipeAreaAdjust;
+            downY = rect.centerY();
+            upX = rect.left + swipeAreaAdjust;
+            upY = rect.centerY();
+        }
+        return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
+    }
+
+    /**
+     * Performs a backwards fling action with the default number of fling
+     * steps (5). If the swipe direction is set to vertical,
+     * then the swipe will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, and false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean flingBackward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollBackward(FLING_STEPS);
+    }
+
+    /**
+     * Performs a backward scroll with the default number of scroll steps (55).
+     * If the swipe direction is set to vertical,
+     * then the swipes will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @return true if scrolled, and false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollBackward() throws UiObjectNotFoundException {
+        Tracer.trace();
+        return scrollBackward(SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a backward scroll. If the swipe direction is set to vertical,
+     * then the swipes will be performed from top to bottom. If the swipe
+     * direction is set to horizontal, then the swipes will be performed from
+     * left to right. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps number of steps. Use this to control the speed of the scroll action.
+     * @return true if scrolled, false if can't scroll anymore
+     * @since API Level 16
+     */
+    public boolean scrollBackward(int steps) throws UiObjectNotFoundException {
+        Tracer.trace(steps);
+        Log.d(LOG_TAG, "scrollBackward() on selector = " + getSelector());
+        AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
+        if (node == null) {
+            throw new UiObjectNotFoundException(getSelector().toString());
+        }
+        Rect rect = new Rect();
+        node.getBoundsInScreen(rect);
+
+        int downX = 0;
+        int downY = 0;
+        int upX = 0;
+        int upY = 0;
+
+        // scrolling is by default assumed vertically unless the object is explicitly
+        // set otherwise by setAsHorizontalContainer()
+        if(mIsVerticalList) {
+            int swipeAreaAdjust = (int)(rect.height() * getSwipeDeadZonePercentage());
+            Log.d(LOG_TAG, "scrollToBegining() using vertical scroll");
+            // scroll vertically: swipe up -> down
+            downX = rect.centerX();
+            downY = rect.top + swipeAreaAdjust;
+            upX = rect.centerX();
+            upY = rect.bottom - swipeAreaAdjust;
+        } else {
+            int swipeAreaAdjust = (int)(rect.width() * getSwipeDeadZonePercentage());
+            Log.d(LOG_TAG, "scrollToBegining() using hotizontal scroll");
+            // scroll horizontally: swipe left -> right
+            // TODO: Assuming device is not in right to left language
+            downX = rect.left + swipeAreaAdjust;
+            downY = rect.centerY();
+            upX = rect.right - swipeAreaAdjust;
+            upY = rect.centerY();
+        }
+        return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
+    }
+
+    /**
+     * Scrolls to the beginning of a scrollable layout element. The beginning
+     * can be at the  top-most edge in the case of vertical controls, or the
+     * left-most edge for horizontal controls. Make sure to take into account
+     * devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps use steps to control the speed, so that it may be a scroll, or fling
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToBeginning(int maxSwipes, int steps) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes, steps);
+        Log.d(LOG_TAG, "scrollToBeginning() on selector = " + getSelector());
+        // protect against potential hanging and return after preset attempts
+        for(int x = 0; x < maxSwipes; x++) {
+            if(!scrollBackward(steps)) {
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Scrolls to the beginning of a scrollable layout element. The beginning
+     * can be at the  top-most edge in the case of vertical controls, or the
+     * left-most edge for horizontal controls. Make sure to take into account
+     * devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToBeginning(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToBeginning(maxSwipes, SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a fling gesture to reach the beginning of a scrollable layout element.
+     * The beginning can be at the  top-most edge in the case of vertical controls, or
+     * the left-most edge for horizontal controls. Make sure to take into
+     * account devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean flingToBeginning(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToBeginning(maxSwipes, FLING_STEPS);
+    }
+
+    /**
+     * Scrolls to the end of a scrollable layout element. The end can be at the
+     * bottom-most edge in the case of vertical controls, or the right-most edge for
+     * horizontal controls. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param steps use steps to control the speed, so that it may be a scroll, or fling
+     * @return true on scrolled else false
+     * @since API Level 16
+     */
+    public boolean scrollToEnd(int maxSwipes, int steps) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes, steps);
+        // protect against potential hanging and return after preset attempts
+        for(int x = 0; x < maxSwipes; x++) {
+            if(!scrollForward(steps)) {
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Scrolls to the end of a scrollable layout element. The end can be at the
+     * bottom-most edge in the case of vertical controls, or the right-most edge for
+     * horizontal controls. Make sure to take into account devices configured with
+     * right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled, else false
+     * @since API Level 16
+     */
+    public boolean scrollToEnd(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToEnd(maxSwipes, SCROLL_STEPS);
+    }
+
+    /**
+     * Performs a fling gesture to reach the end of a scrollable layout element.
+     * The end can be at the  bottom-most edge in the case of vertical controls, or
+     * the right-most edge for horizontal controls. Make sure to take into
+     * account devices configured with right-to-left languages like Arabic and Hebrew.
+     *
+     * @param maxSwipes
+     * @return true on scrolled, else false
+     * @since API Level 16
+     */
+    public boolean flingToEnd(int maxSwipes) throws UiObjectNotFoundException {
+        Tracer.trace(maxSwipes);
+        return scrollToEnd(maxSwipes, FLING_STEPS);
+    }
+
+    /**
+     * Returns the percentage of a widget's size that's considered as a no-touch
+     * zone when swiping. The no-touch zone is set as a percentage of a widget's total
+     * width or height, denoting a margin around the swipable area of the widget.
+     * Swipes must start and end inside this margin. This is important when the
+     * widget being swiped may not respond to the swipe if started at a point
+     * too near to the edge. The default is 10% from either edge.
+     *
+     * @return a value between 0 and 1
+     * @since API Level 16
+     */
+    public double getSwipeDeadZonePercentage() {
+        Tracer.trace();
+        return mSwipeDeadZonePercentage;
+    }
+
+    /**
+     * Sets the percentage of a widget's size that's considered as no-touch
+     * zone when swiping.
+     * The no-touch zone is set as percentage of a widget's total width or height,
+     * denoting a margin around the swipable area of the widget. Swipes must
+     * always start and end inside this margin. This is important when the
+     * widget being swiped may not respond to the swipe if started at a point
+     * too near to the edge. The default is 10% from either edge.
+     *
+     * @param swipeDeadZonePercentage is a value between 0 and 1
+     * @return reference to itself
+     * @since API Level 16
+     */
+    public UiScrollable setSwipeDeadZonePercentage(double swipeDeadZonePercentage) {
+        Tracer.trace(swipeDeadZonePercentage);
+        mSwipeDeadZonePercentage = swipeDeadZonePercentage;
+        return this;
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiSelector.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiSelector.java
new file mode 100644
index 0000000..482a74d
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiSelector.java
@@ -0,0 +1,1022 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.util.SparseArray;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.util.regex.Pattern;
+
+/**
+ * Specifies the elements in the layout hierarchy for tests to target, filtered
+ * by properties such as text value, content-description, class name, and state
+ * information. You can also target an element by its location in a layout
+ * hierarchy.
+ * @since API Level 16
+ */
+public class UiSelector {
+    static final int SELECTOR_NIL = 0;
+    static final int SELECTOR_TEXT = 1;
+    static final int SELECTOR_START_TEXT = 2;
+    static final int SELECTOR_CONTAINS_TEXT = 3;
+    static final int SELECTOR_CLASS = 4;
+    static final int SELECTOR_DESCRIPTION = 5;
+    static final int SELECTOR_START_DESCRIPTION = 6;
+    static final int SELECTOR_CONTAINS_DESCRIPTION = 7;
+    static final int SELECTOR_INDEX = 8;
+    static final int SELECTOR_INSTANCE = 9;
+    static final int SELECTOR_ENABLED = 10;
+    static final int SELECTOR_FOCUSED = 11;
+    static final int SELECTOR_FOCUSABLE = 12;
+    static final int SELECTOR_SCROLLABLE = 13;
+    static final int SELECTOR_CLICKABLE = 14;
+    static final int SELECTOR_CHECKED = 15;
+    static final int SELECTOR_SELECTED = 16;
+    static final int SELECTOR_ID = 17;
+    static final int SELECTOR_PACKAGE_NAME = 18;
+    static final int SELECTOR_CHILD = 19;
+    static final int SELECTOR_CONTAINER = 20;
+    static final int SELECTOR_PATTERN = 21;
+    static final int SELECTOR_PARENT = 22;
+    static final int SELECTOR_COUNT = 23;
+    static final int SELECTOR_LONG_CLICKABLE = 24;
+    static final int SELECTOR_TEXT_REGEX = 25;
+    static final int SELECTOR_CLASS_REGEX = 26;
+    static final int SELECTOR_DESCRIPTION_REGEX = 27;
+    static final int SELECTOR_PACKAGE_NAME_REGEX = 28;
+    static final int SELECTOR_RESOURCE_ID = 29;
+    static final int SELECTOR_CHECKABLE = 30;
+    static final int SELECTOR_RESOURCE_ID_REGEX = 31;
+
+    private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>();
+
+    /**
+     * @since API Level 16
+     */
+    public UiSelector() {
+    }
+
+    UiSelector(UiSelector selector) {
+        mSelectorAttributes = selector.cloneSelector().mSelectorAttributes;
+    }
+
+    /**
+     * @since API Level 17
+     */
+    protected UiSelector cloneSelector() {
+        UiSelector ret = new UiSelector();
+        ret.mSelectorAttributes = mSelectorAttributes.clone();
+        if (hasChildSelector())
+            ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector()));
+        if (hasParentSelector())
+            ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector()));
+        if (hasPatternSelector())
+            ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector()));
+        return ret;
+    }
+
+    static UiSelector patternBuilder(UiSelector selector) {
+        if (!selector.hasPatternSelector()) {
+            return new UiSelector().patternSelector(selector);
+        }
+        return selector;
+    }
+
+    static UiSelector patternBuilder(UiSelector container, UiSelector pattern) {
+        return new UiSelector(
+                new UiSelector().containerSelector(container).patternSelector(pattern));
+    }
+
+    /**
+     * Set the search criteria to match the visible text displayed
+     * in a widget (for example, the text label to launch an app).
+     *
+     * The text for the element must match exactly with the string in your input
+     * argument. Matching is case-sensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector text(String text) {
+        return buildSelector(SELECTOR_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the visible text displayed in a layout
+     * element, using a regular expression.
+     *
+     * The text in the widget must match exactly with the string in your
+     * input argument.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector textMatches(String regex) {
+        return buildSelector(SELECTOR_TEXT_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match visible text in a widget that is
+     * prefixed by the text parameter.
+     *
+     * The matching is case-insensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector textStartsWith(String text) {
+        return buildSelector(SELECTOR_START_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the visible text in a widget
+     * where the visible text must contain the string in your input argument.
+     *
+     * The matching is case-sensitive.
+     *
+     * @param text Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector textContains(String text) {
+        return buildSelector(SELECTOR_CONTAINS_TEXT, text);
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget (for example, "android.widget.Button").
+     *
+     * @param className Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector className(String className) {
+        return buildSelector(SELECTOR_CLASS, className);
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget, using a regular expression.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector classNameMatches(String regex) {
+        return buildSelector(SELECTOR_CLASS_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the class property
+     * for a widget (for example, "android.widget.Button").
+     *
+     * @param type type
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public <T> UiSelector className(Class<T> type) {
+        return buildSelector(SELECTOR_CLASS, type.getName());
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must match exactly
+     * with the string in your input argument.
+     *
+     * Matching is case-sensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector description(String desc) {
+        return buildSelector(SELECTOR_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must match exactly
+     * with the string in your input argument.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector descriptionMatches(String regex) {
+        return buildSelector(SELECTOR_DESCRIPTION_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must start
+     * with the string in your input argument.
+     *
+     * Matching is case-insensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector descriptionStartsWith(String desc) {
+        return buildSelector(SELECTOR_START_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the content-description
+     * property for a widget.
+     *
+     * The content-description is typically used
+     * by the Android Accessibility framework to
+     * provide an audio prompt for the widget when
+     * the widget is selected. The content-description
+     * for the widget must contain
+     * the string in your input argument.
+     *
+     * Matching is case-insensitive.
+     *
+     * @param desc Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector descriptionContains(String desc) {
+        return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
+    }
+
+    /**
+     * Set the search criteria to match the given resource ID.
+     *
+     * @param id Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector resourceId(String id) {
+        return buildSelector(SELECTOR_RESOURCE_ID, id);
+    }
+
+    /**
+     * Set the search criteria to match the resource ID
+     * of the widget, using a regular expression.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector resourceIdMatches(String regex) {
+        return buildSelector(SELECTOR_RESOURCE_ID_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Set the search criteria to match the widget by its node
+     * index in the layout hierarchy.
+     *
+     * The index value must be 0 or greater.
+     *
+     * Using the index can be unreliable and should only
+     * be used as a last resort for matching. Instead,
+     * consider using the {@link #instance(int)} method.
+     *
+     * @param index Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector index(final int index) {
+        return buildSelector(SELECTOR_INDEX, index);
+    }
+
+    /**
+     * Set the search criteria to match the
+     * widget by its instance number.
+     *
+     * The instance value must be 0 or greater, where
+     * the first instance is 0.
+     *
+     * For example, to simulate a user click on
+     * the third image that is enabled in a UI screen, you
+     * could specify a a search criteria where the instance is
+     * 2, the {@link #className(String)} matches the image
+     * widget class, and {@link #enabled(boolean)} is true.
+     * The code would look like this:
+     * <code>
+     * new UiSelector().className("android.widget.ImageView")
+     *    .enabled(true).instance(2);
+     * </code>
+     *
+     * @param instance Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector instance(final int instance) {
+        return buildSelector(SELECTOR_INSTANCE, instance);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are enabled.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector enabled(boolean val) {
+        return buildSelector(SELECTOR_ENABLED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that have focus.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector focused(boolean val) {
+        return buildSelector(SELECTOR_FOCUSED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are focusable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector focusable(boolean val) {
+        return buildSelector(SELECTOR_FOCUSABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are scrollable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector scrollable(boolean val) {
+        return buildSelector(SELECTOR_SCROLLABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that
+     * are currently selected.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector selected(boolean val) {
+        return buildSelector(SELECTOR_SELECTED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that
+     * are currently checked (usually for checkboxes).
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector checked(boolean val) {
+        return buildSelector(SELECTOR_CHECKED, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are clickable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector clickable(boolean val) {
+        return buildSelector(SELECTOR_CLICKABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are checkable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 18
+     */
+    public UiSelector checkable(boolean val) {
+        return buildSelector(SELECTOR_CHECKABLE, val);
+    }
+
+    /**
+     * Set the search criteria to match widgets that are long-clickable.
+     *
+     * Typically, using this search criteria alone is not useful.
+     * You should also include additional criteria, such as text,
+     * content-description, or the class name for a widget.
+     *
+     * If no other search criteria is specified, and there is more
+     * than one matching widget, the first widget in the tree
+     * is selected.
+     *
+     * @param val Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector longClickable(boolean val) {
+        return buildSelector(SELECTOR_LONG_CLICKABLE, val);
+    }
+
+    /**
+     * Adds a child UiSelector criteria to this selector.
+     *
+     * Use this selector to narrow the search scope to
+     * child widgets under a specific parent widget.
+     *
+     * @param selector
+     * @return UiSelector with this added search criterion
+     * @since API Level 16
+     */
+    public UiSelector childSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_CHILD, selector);
+    }
+
+    private UiSelector patternSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_PATTERN, selector);
+    }
+
+    private UiSelector containerSelector(UiSelector selector) {
+        return buildSelector(SELECTOR_CONTAINER, selector);
+    }
+
+    /**
+     * Adds a child UiSelector criteria to this selector which is used to
+     * start search from the parent widget.
+     *
+     * Use this selector to narrow the search scope to
+     * sibling widgets as well all child widgets under a parent.
+     *
+     * @param selector
+     * @return UiSelector with this added search criterion
+     * @since API Level 16
+     */
+    public UiSelector fromParent(UiSelector selector) {
+        return buildSelector(SELECTOR_PARENT, selector);
+    }
+
+    /**
+     * Set the search criteria to match the package name
+     * of the application that contains the widget.
+     *
+     * @param name Value to match
+     * @return UiSelector with the specified search criteria
+     * @since API Level 16
+     */
+    public UiSelector packageName(String name) {
+        return buildSelector(SELECTOR_PACKAGE_NAME, name);
+    }
+
+    /**
+     * Set the search criteria to match the package name
+     * of the application that contains the widget.
+     *
+     * @param regex a regular expression
+     * @return UiSelector with the specified search criteria
+     * @since API Level 17
+     */
+    public UiSelector packageNameMatches(String regex) {
+        return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, Pattern.compile(regex));
+    }
+
+    /**
+     * Building a UiSelector always returns a new UiSelector and never modifies the
+     * existing UiSelector being used.
+     */
+    private UiSelector buildSelector(int selectorId, Object selectorValue) {
+        UiSelector selector = new UiSelector(this);
+        if (selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT)
+            selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue);
+        else
+            selector.mSelectorAttributes.put(selectorId, selectorValue);
+        return selector;
+    }
+
+    /**
+     * Selectors may have a hierarchy defined by specifying child nodes to be matched.
+     * It is not necessary that every selector have more than one level. A selector
+     * can also be a single level referencing only one node. In such cases the return
+     * it null.
+     *
+     * @return a child selector if one exists. Else null if this selector does not
+     * reference child node.
+     */
+    UiSelector getChildSelector() {
+        UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getPatternSelector() {
+        UiSelector selector =
+                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getContainerSelector() {
+        UiSelector selector =
+                (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    UiSelector getParentSelector() {
+        UiSelector selector =
+                (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null);
+        if (selector != null)
+            return new UiSelector(selector);
+        return null;
+    }
+
+    int getInstance() {
+        return getInt(UiSelector.SELECTOR_INSTANCE);
+    }
+
+    String getString(int criterion) {
+        return (String) mSelectorAttributes.get(criterion, null);
+    }
+
+    boolean getBoolean(int criterion) {
+        return (Boolean) mSelectorAttributes.get(criterion, false);
+    }
+
+    int getInt(int criterion) {
+        return (Integer) mSelectorAttributes.get(criterion, 0);
+    }
+
+    Pattern getPattern(int criterion) {
+        return (Pattern) mSelectorAttributes.get(criterion, null);
+    }
+
+    boolean isMatchFor(AccessibilityNodeInfo node, int index) {
+        int size = mSelectorAttributes.size();
+        for(int x = 0; x < size; x++) {
+            CharSequence s = null;
+            int criterion = mSelectorAttributes.keyAt(x);
+            switch(criterion) {
+            case UiSelector.SELECTOR_INDEX:
+                if (index != this.getInt(criterion))
+                    return false;
+                break;
+            case UiSelector.SELECTOR_CHECKED:
+                if (node.isChecked() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLASS:
+                s = node.getClassName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLASS_REGEX:
+                s = node.getClassName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CLICKABLE:
+                if (node.isClickable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CHECKABLE:
+                if (node.isCheckable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_LONG_CLICKABLE:
+                if (node.isLongClickable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CONTAINS_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().toLowerCase()
+                        .contains(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_START_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().toLowerCase()
+                        .startsWith(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_DESCRIPTION:
+                s = node.getContentDescription();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_DESCRIPTION_REGEX:
+                s = node.getContentDescription();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_CONTAINS_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().toLowerCase()
+                        .contains(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_START_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().toLowerCase()
+                        .startsWith(getString(criterion).toLowerCase())) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_TEXT:
+                s = node.getText();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_TEXT_REGEX:
+                s = node.getText();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_ENABLED:
+                if (node.isEnabled() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_FOCUSABLE:
+                if (node.isFocusable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_FOCUSED:
+                if (node.isFocused() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_ID:
+                break; //TODO: do we need this for AccessibilityNodeInfo.id?
+            case UiSelector.SELECTOR_PACKAGE_NAME:
+                s = node.getPackageName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_PACKAGE_NAME_REGEX:
+                s = node.getPackageName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_SCROLLABLE:
+                if (node.isScrollable() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_SELECTED:
+                if (node.isSelected() != getBoolean(criterion)) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_RESOURCE_ID:
+                s = node.getViewIdResourceName();
+                if (s == null || !s.toString().contentEquals(getString(criterion))) {
+                    return false;
+                }
+                break;
+            case UiSelector.SELECTOR_RESOURCE_ID_REGEX:
+                s = node.getViewIdResourceName();
+                if (s == null || !getPattern(criterion).matcher(s).matches()) {
+                    return false;
+                }
+                break;
+            }
+        }
+        return matchOrUpdateInstance();
+    }
+
+    private boolean matchOrUpdateInstance() {
+        int currentSelectorCounter = 0;
+        int currentSelectorInstance = 0;
+
+        // matched attributes - now check for matching instance number
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) >= 0) {
+            currentSelectorInstance =
+                    (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE);
+        }
+
+        // instance is required. Add count if not already counting
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) >= 0) {
+            currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT);
+        }
+
+        // Verify
+        if (currentSelectorInstance == currentSelectorCounter) {
+            return true;
+        }
+        // Update count
+        if (currentSelectorInstance > currentSelectorCounter) {
+            mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter);
+        }
+        return false;
+    }
+
+    /**
+     * Leaf selector indicates no more child or parent selectors
+     * are declared in the this selector.
+     * @return true if is leaf.
+     */
+    boolean isLeaf() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 &&
+                mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
+            return true;
+        }
+        return false;
+    }
+
+    boolean hasChildSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasPatternSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasContainerSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasParentSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the deepest selector in the chain of possible sub selectors.
+     * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)}
+     * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of
+     * a selector.
+     * @return last UiSelector in chain
+     */
+    private UiSelector getLastSubSelector() {
+        if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) {
+            UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD);
+            if (child.getLastSubSelector() == null) {
+                return child;
+            }
+            return child.getLastSubSelector();
+        } else if (mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) {
+            UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT);
+            if (parent.getLastSubSelector() == null) {
+                return parent;
+            }
+            return parent.getLastSubSelector();
+        }
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return dumpToString(true);
+    }
+
+    String dumpToString(boolean all) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(UiSelector.class.getSimpleName() + "[");
+        final int criterionCount = mSelectorAttributes.size();
+        for (int i = 0; i < criterionCount; i++) {
+            if (i > 0) {
+                builder.append(", ");
+            }
+            final int criterion = mSelectorAttributes.keyAt(i);
+            switch (criterion) {
+            case SELECTOR_TEXT:
+                builder.append("TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_TEXT_REGEX:
+                builder.append("TEXT_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_START_TEXT:
+                builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CONTAINS_TEXT:
+                builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLASS:
+                builder.append("CLASS=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLASS_REGEX:
+                builder.append("CLASS_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_DESCRIPTION:
+                builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_DESCRIPTION_REGEX:
+                builder.append("DESCRIPTION_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_START_DESCRIPTION:
+                builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CONTAINS_DESCRIPTION:
+                builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_INDEX:
+                builder.append("INDEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_INSTANCE:
+                builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_ENABLED:
+                builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_FOCUSED:
+                builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_FOCUSABLE:
+                builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_SCROLLABLE:
+                builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CLICKABLE:
+                builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHECKABLE:
+                builder.append("CHECKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_LONG_CLICKABLE:
+                builder.append("LONG_CLICKABLE=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHECKED:
+                builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_SELECTED:
+                builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_ID:
+                builder.append("ID=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_CHILD:
+                if (all)
+                    builder.append("CHILD=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("CHILD[..]");
+                break;
+            case SELECTOR_PATTERN:
+                if (all)
+                    builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("PATTERN[..]");
+                break;
+            case SELECTOR_CONTAINER:
+                if (all)
+                    builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("CONTAINER[..]");
+                break;
+            case SELECTOR_PARENT:
+                if (all)
+                    builder.append("PARENT=").append(mSelectorAttributes.valueAt(i));
+                else
+                    builder.append("PARENT[..]");
+                break;
+            case SELECTOR_COUNT:
+                builder.append("COUNT=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_PACKAGE_NAME:
+                builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_PACKAGE_NAME_REGEX:
+                builder.append("PACKAGE_NAME_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_RESOURCE_ID:
+                builder.append("RESOURCE_ID=").append(mSelectorAttributes.valueAt(i));
+                break;
+            case SELECTOR_RESOURCE_ID_REGEX:
+                builder.append("RESOURCE_ID_REGEX=").append(mSelectorAttributes.valueAt(i));
+                break;
+            default:
+                builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i));
+            }
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiWatcher.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiWatcher.java
new file mode 100644
index 0000000..5403e30
--- /dev/null
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/UiWatcher.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+package com.android.uiautomator.core;
+
+/**
+ * See {@link UiDevice#registerWatcher(String, UiWatcher)} on how to register a
+ * a condition watcher to be called by the automation library. The automation library will
+ * invoke checkForCondition() only when a regular API call is in retry mode because it is unable
+ * to locate its selector yet. Only during this time, the watchers are invoked to check if there is
+ * something else unexpected on the screen.
+ * @since API Level 16
+ */
+public interface UiWatcher {
+
+    /**
+     * Custom handler that is automatically called when the testing framework is unable to
+     * find a match using the {@link UiSelector}
+     *
+     * When the framework is in the process of matching a {@link UiSelector} and it
+     * is unable to match any widget based on the specified criteria in the selector,
+     * the framework will perform retries for a predetermined time, waiting for the display
+     * to update and show the desired widget. While the framework is in this state, it will call
+     * registered watchers' checkForCondition(). This gives the registered watchers a chance
+     * to take a look at the display and see if there is a recognized condition that can be
+     * handled and in doing so allowing the current test to continue.
+     *
+     * An example usage would be to look for dialogs popped due to other background
+     * processes requesting user attention and have nothing to do with the application
+     * currently under test.
+     *
+     * @return true to indicate a matched condition or false for nothing was matched
+     * @since API Level 16
+     */
+    public boolean checkForCondition();
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
new file mode 100644
index 0000000..c551482
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.core;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.IActivityManager.ContentProviderHolder;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.database.Cursor;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWindowManager;
+
+/**
+ * @hide
+ */
+public class ShellUiAutomatorBridge extends UiAutomatorBridge {
+
+    private static final String LOG_TAG = ShellUiAutomatorBridge.class.getSimpleName();
+
+    public ShellUiAutomatorBridge(UiAutomation uiAutomation) {
+        super(uiAutomation);
+    }
+
+    public Display getDefaultDisplay() {
+        return DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+    }
+
+    public long getSystemLongPressTime() {
+        // Read the long press timeout setting.
+        long longPressTimeout = 0;
+        try {
+            IContentProvider provider = null;
+            Cursor cursor = null;
+            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            String providerName = Settings.Secure.CONTENT_URI.getAuthority();
+            IBinder token = new Binder();
+            try {
+                ContentProviderHolder holder = activityManager.getContentProviderExternal(
+                        providerName, UserHandle.USER_OWNER, token);
+                if (holder == null) {
+                    throw new IllegalStateException("Could not find provider: " + providerName);
+                }
+                provider = holder.provider;
+                cursor = provider.query(null, Settings.Secure.CONTENT_URI,
+                        new String[] {
+                            Settings.Secure.VALUE
+                        }, "name=?",
+                        new String[] {
+                            Settings.Secure.LONG_PRESS_TIMEOUT
+                        }, null, null);
+                if (cursor.moveToFirst()) {
+                    longPressTimeout = cursor.getInt(0);
+                }
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+                if (provider != null) {
+                    activityManager.removeContentProviderExternal(providerName, token);
+                }
+            }
+        } catch (RemoteException e) {
+            String message = "Error reading long press timeout setting.";
+            Log.e(LOG_TAG, message, e);
+            throw new RuntimeException(message, e);
+        }
+        return longPressTimeout;
+    }
+
+    @Override
+    public int getRotation() {
+        IWindowManager wm =
+                IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
+        int ret = -1;
+        try {
+            ret = wm.getRotation();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Error getting screen rotation", e);
+            throw new RuntimeException(e);
+        }
+        return ret;
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        IPowerManager pm =
+                IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
+        boolean ret = false;
+        try {
+            ret = pm.isInteractive();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Error getting screen status", e);
+            throw new RuntimeException(e);
+        }
+        return ret;
+    }
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
new file mode 100644
index 0000000..1fa9bac
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -0,0 +1,127 @@
+package com.android.uiautomator.core;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.IActivityController;
+import android.app.IActivityManager;
+import android.app.UiAutomation;
+import android.app.UiAutomationConnection;
+import android.content.Intent;
+import android.os.HandlerThread;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ */
+public class UiAutomationShellWrapper {
+
+    private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread";
+
+    private final HandlerThread mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+
+    private UiAutomation mUiAutomation;
+
+    public void connect() {
+        if (mHandlerThread.isAlive()) {
+            throw new IllegalStateException("Already connected!");
+        }
+        mHandlerThread.start();
+        mUiAutomation = new UiAutomation(mHandlerThread.getLooper(),
+                new UiAutomationConnection());
+        mUiAutomation.connect();
+    }
+
+    /**
+     * Enable or disable monkey test mode.
+     *
+     * Setting test as "monkey" indicates to some applications that a test framework is
+     * running as a "monkey" type. Such applications may choose not to perform actions that
+     * do submits so to avoid allowing monkey tests from doing harm or performing annoying
+     * actions such as dialing 911 or posting messages to public forums, etc.
+     *
+     * @param isSet True to set as monkey test. False to set as regular functional test (default).
+     * @see {@link ActivityManager#isUserAMonkey()}
+     */
+    public void setRunAsMonkey(boolean isSet) {
+        IActivityManager am = ActivityManagerNative.getDefault();
+        if (am == null) {
+            throw new RuntimeException("Can't manage monkey status; is the system running?");
+        }
+        try {
+            if (isSet) {
+                am.setActivityController(new DummyActivityController());
+            } else {
+                am.setActivityController(null);
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void disconnect() {
+        if (!mHandlerThread.isAlive()) {
+            throw new IllegalStateException("Already disconnected!");
+        }
+        mUiAutomation.disconnect();
+        mHandlerThread.quit();
+    }
+
+    public UiAutomation getUiAutomation() {
+        return mUiAutomation;
+    }
+
+    public void setCompressedLayoutHierarchy(boolean compressed) {
+        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
+        if (compressed)
+            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        else
+            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        mUiAutomation.setServiceInfo(info);
+    }
+
+    /**
+     * Dummy, no interference, activity controller.
+     */
+    private class DummyActivityController extends IActivityController.Stub {
+        @Override
+        public boolean activityStarting(Intent intent, String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean activityResuming(String pkg) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
+                long timeMillis, String stackTrace) throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return true;
+        }
+
+        @Override
+        public int appEarlyNotResponding(String processName, int pid, String annotation)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+
+        @Override
+        public int appNotResponding(String processName, int pid, String processStats)
+                throws RemoteException {
+            /* do nothing and let activity proceed normally */
+            return 0;
+        }
+
+        @Override
+        public int systemNotResponding(String message)
+                throws RemoteException {
+            /* do nothing and let system proceed normally */
+            return 0;
+        }
+    }
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
new file mode 100644
index 0000000..f0c60d2
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/IAutomationSupport.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import android.os.Bundle;
+
+/**
+ * Provides auxiliary support for running test cases
+ *
+ * @since API Level 16
+ */
+public interface IAutomationSupport {
+
+    /**
+     * Allows the running test cases to send out interim status
+     *
+     * @param resultCode
+     * @param status status report, consisting of key value pairs
+     * @since API Level 16
+     */
+    public void sendStatus(int resultCode, Bundle status);
+
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java
new file mode 100644
index 0000000..cda49f6
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/TestCaseCollector.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A convenient class that encapsulates functions for adding test classes
+ *
+ * @hide
+ */
+public class TestCaseCollector {
+
+    private ClassLoader mClassLoader;
+    private List<TestCase> mTestCases;
+    private TestCaseFilter mFilter;
+
+    public TestCaseCollector(ClassLoader classLoader, TestCaseFilter filter) {
+        mClassLoader = classLoader;
+        mTestCases = new ArrayList<TestCase>();
+        mFilter = filter;
+    }
+
+    /**
+     * Adds classes to test by providing a list of class names in string
+     *
+     * The class name may be in "<class name>#<method name>" format
+     *
+     * @param classNames class must be subclass of {@link UiAutomatorTestCase}
+     * @throws ClassNotFoundException
+     */
+    public void addTestClasses(List<String> classNames) throws ClassNotFoundException {
+        for (String className : classNames) {
+            addTestClass(className);
+        }
+    }
+
+    /**
+     * Adds class to test by providing class name in string.
+     *
+     * The class name may be in "<class name>#<method name>" format
+     *
+     * @param className classes must be subclass of {@link UiAutomatorTestCase}
+     * @throws ClassNotFoundException
+     */
+    public void addTestClass(String className) throws ClassNotFoundException {
+        int hashPos = className.indexOf('#');
+        String methodName = null;
+        if (hashPos != -1) {
+            methodName = className.substring(hashPos + 1);
+            className = className.substring(0, hashPos);
+        }
+        addTestClass(className, methodName);
+    }
+
+    /**
+     * Adds class to test by providing class name and method name in separate strings
+     *
+     * @param className class must be subclass of {@link UiAutomatorTestCase}
+     * @param methodName may be null, in which case all "public void testNNN(void)" functions
+     *                   will be added
+     * @throws ClassNotFoundException
+     */
+    public void addTestClass(String className, String methodName) throws ClassNotFoundException {
+        Class<?> clazz = mClassLoader.loadClass(className);
+        if (methodName != null) {
+            addSingleTestMethod(clazz, methodName);
+        } else {
+            Method[] methods = clazz.getMethods();
+            for (Method method : methods) {
+                if (mFilter.accept(method)) {
+                    addSingleTestMethod(clazz, method.getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the list of added test cases so far
+     * @return a list of {@link TestCase}
+     */
+    public List<TestCase> getTestCases() {
+        return Collections.unmodifiableList(mTestCases);
+    }
+
+    protected void addSingleTestMethod(Class<?> clazz, String method) {
+        if (!(mFilter.accept(clazz))) {
+            throw new RuntimeException("Test class must be derived from UiAutomatorTestCase");
+        }
+        try {
+            TestCase testCase = (TestCase) clazz.newInstance();
+            testCase.setName(method);
+            mTestCases.add(testCase);
+        } catch (InstantiationException e) {
+            mTestCases.add(error(clazz, "InstantiationException: could not instantiate " +
+                    "test class. Class: " + clazz.getName()));
+        } catch (IllegalAccessException e) {
+            mTestCases.add(error(clazz, "IllegalAccessException: could not instantiate " +
+                    "test class. Class: " + clazz.getName()));
+        }
+    }
+
+    private UiAutomatorTestCase error(Class<?> clazz, final String message) {
+        UiAutomatorTestCase warning = new UiAutomatorTestCase() {
+            protected void runTest() {
+                fail(message);
+            }
+        };
+
+        warning.setName(clazz.getName());
+        return warning;
+    }
+
+    /**
+     * Determine if a class and its method should be accepted into test suite
+     *
+     */
+    public interface TestCaseFilter {
+
+        /**
+         * Determine that based on the method signature, if it can be accepted
+         * @param method
+         */
+        public boolean accept(Method method);
+
+        /**
+         * Determine that based on the class type, if it can be accepted
+         * @param clazz
+         * @return
+         */
+        public boolean accept(Class<?> clazz);
+    }
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
new file mode 100644
index 0000000..e7d961b
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCase.java
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.view.inputmethod.InputMethodInfo;
+
+import com.android.internal.view.IInputMethodManager;
+import com.android.uiautomator.core.UiDevice;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * UI automation test should extend this class. This class provides access
+ * to the following:
+ * {@link UiDevice} instance
+ * {@link Bundle} for command line parameters.
+ * @since API Level 16
+ */
+public class UiAutomatorTestCase extends TestCase {
+
+    private static final String DISABLE_IME = "disable_ime";
+    private static final String DUMMY_IME_PACKAGE = "com.android.testing.dummyime";
+    private UiDevice mUiDevice;
+    private Bundle mParams;
+    private IAutomationSupport mAutomationSupport;
+    private boolean mShouldDisableIme = false;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mShouldDisableIme = "true".equals(mParams.getString(DISABLE_IME));
+        if (mShouldDisableIme) {
+            setDummyIme();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mShouldDisableIme) {
+            restoreActiveIme();
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Get current instance of {@link UiDevice}. Works similar to calling the static
+     * {@link UiDevice#getInstance()} from anywhere in the test classes.
+     * @since API Level 16
+     */
+    public UiDevice getUiDevice() {
+        return mUiDevice;
+    }
+
+    /**
+     * Get command line parameters. On the command line when passing <code>-e key value</code>
+     * pairs, the {@link Bundle} will have the key value pairs conveniently available to the
+     * tests.
+     * @since API Level 16
+     */
+    public Bundle getParams() {
+        return mParams;
+    }
+
+    /**
+     * Provides support for running tests to report interim status
+     *
+     * @return IAutomationSupport
+     * @since API Level 16
+     */
+    public IAutomationSupport getAutomationSupport() {
+        return mAutomationSupport;
+    }
+
+    /**
+     * package private
+     * @param uiDevice
+     */
+    void setUiDevice(UiDevice uiDevice) {
+        mUiDevice = uiDevice;
+    }
+
+    /**
+     * package private
+     * @param params
+     */
+    void setParams(Bundle params) {
+        mParams = params;
+    }
+
+    void setAutomationSupport(IAutomationSupport automationSupport) {
+        mAutomationSupport = automationSupport;
+    }
+
+    /**
+     * Calls {@link SystemClock#sleep(long)} to sleep
+     * @param ms is in milliseconds.
+     * @since API Level 16
+     */
+    public void sleep(long ms) {
+        SystemClock.sleep(ms);
+    }
+
+    private void setDummyIme() throws RemoteException {
+        IInputMethodManager im = IInputMethodManager.Stub.asInterface(ServiceManager
+                .getService(Context.INPUT_METHOD_SERVICE));
+        List<InputMethodInfo> infos = im.getInputMethodList();
+        String id = null;
+        for (InputMethodInfo info : infos) {
+            if (DUMMY_IME_PACKAGE.equals(info.getComponent().getPackageName())) {
+                id = info.getId();
+            }
+        }
+        if (id == null) {
+            throw new RuntimeException(String.format(
+                    "Required testing fixture missing: IME package (%s)", DUMMY_IME_PACKAGE));
+        }
+        im.setInputMethod(null, id);
+    }
+
+    private void restoreActiveIme() throws RemoteException {
+        // TODO: figure out a way to restore active IME
+        // Currently retrieving active IME requires querying secure settings provider, which is hard
+        // to do without a Context; so the caveat here is that to make the post test device usable,
+        // the active IME needs to be manually switched.
+    }
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java
new file mode 100644
index 0000000..1de5a4d
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestCaseFilter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import com.android.uiautomator.testrunner.TestCaseCollector.TestCaseFilter;
+
+import java.lang.reflect.Method;
+
+/**
+ * A {@link TestCaseFilter} that accepts testFoo methods and {@link UiAutomatorTestCase} classes
+ *
+ * @hide
+ */
+public class UiAutomatorTestCaseFilter implements TestCaseFilter {
+
+    @Override
+    public boolean accept(Method method) {
+        return ((method.getParameterTypes().length == 0) &&
+                (method.getName().startsWith("test")) &&
+                (method.getReturnType().getSimpleName().equals("void")));
+    }
+
+    @Override
+    public boolean accept(Class<?> clazz) {
+        return UiAutomatorTestCase.class.isAssignableFrom(clazz);
+    }
+
+}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
new file mode 100644
index 0000000..ef167f9
--- /dev/null
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
@@ -0,0 +1,431 @@
+/*
+ * 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.
+ */
+
+package com.android.uiautomator.testrunner;
+
+import android.app.Activity;
+import android.app.IInstrumentationWatcher;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.test.RepetitiveTest;
+import android.util.Log;
+
+import com.android.uiautomator.core.ShellUiAutomatorBridge;
+import com.android.uiautomator.core.Tracer;
+import com.android.uiautomator.core.UiAutomationShellWrapper;
+import com.android.uiautomator.core.UiDevice;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+import junit.textui.ResultPrinter;
+
+/**
+ * @hide
+ */
+public class UiAutomatorTestRunner {
+
+    private static final String LOGTAG = UiAutomatorTestRunner.class.getSimpleName();
+    private static final int EXIT_OK = 0;
+    private static final int EXIT_EXCEPTION = -1;
+
+    private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread";
+
+    private boolean mDebug;
+    private boolean mMonkey;
+    private Bundle mParams = null;
+    private UiDevice mUiDevice;
+    private List<String> mTestClasses = null;
+    private final FakeInstrumentationWatcher mWatcher = new FakeInstrumentationWatcher();
+    private final IAutomationSupport mAutomationSupport = new IAutomationSupport() {
+        @Override
+        public void sendStatus(int resultCode, Bundle status) {
+            mWatcher.instrumentationStatus(null, resultCode, status);
+        }
+    };
+    private final List<TestListener> mTestListeners = new ArrayList<TestListener>();
+
+    private HandlerThread mHandlerThread;
+
+    public void run(List<String> testClasses, Bundle params, boolean debug, boolean monkey) {
+        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread thread, Throwable ex) {
+                Log.e(LOGTAG, "uncaught exception", ex);
+                Bundle results = new Bundle();
+                results.putString("shortMsg", ex.getClass().getName());
+                results.putString("longMsg", ex.getMessage());
+                mWatcher.instrumentationFinished(null, 0, results);
+                // bailing on uncaught exception
+                System.exit(EXIT_EXCEPTION);
+            }
+        });
+
+        mTestClasses = testClasses;
+        mParams = params;
+        mDebug = debug;
+        mMonkey = monkey;
+        start();
+        System.exit(EXIT_OK);
+    }
+
+    /**
+     * Called after all test classes are in place, ready to test
+     */
+    protected void start() {
+        TestCaseCollector collector = getTestCaseCollector(this.getClass().getClassLoader());
+        try {
+            collector.addTestClasses(mTestClasses);
+        } catch (ClassNotFoundException e) {
+            // will be caught by uncaught handler
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        if (mDebug) {
+            Debug.waitForDebugger();
+        }
+        mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+        mHandlerThread.setDaemon(true);
+        mHandlerThread.start();
+        UiAutomationShellWrapper automationWrapper = new UiAutomationShellWrapper();
+        automationWrapper.connect();
+
+        long startTime = SystemClock.uptimeMillis();
+        TestResult testRunResult = new TestResult();
+        ResultReporter resultPrinter;
+        String outputFormat = mParams.getString("outputFormat");
+        List<TestCase> testCases = collector.getTestCases();
+        Bundle testRunOutput = new Bundle();
+        if ("simple".equals(outputFormat)) {
+            resultPrinter = new SimpleResultPrinter(System.out, true);
+        } else {
+            resultPrinter = new WatcherResultPrinter(testCases.size());
+        }
+        try {
+            automationWrapper.setRunAsMonkey(mMonkey);
+            mUiDevice = UiDevice.getInstance();
+            mUiDevice.initialize(new ShellUiAutomatorBridge(automationWrapper.getUiAutomation()));
+
+            String traceType = mParams.getString("traceOutputMode");
+            if(traceType != null) {
+                Tracer.Mode mode = Tracer.Mode.valueOf(Tracer.Mode.class, traceType);
+                if (mode == Tracer.Mode.FILE || mode == Tracer.Mode.ALL) {
+                    String filename = mParams.getString("traceLogFilename");
+                    if (filename == null) {
+                        throw new RuntimeException("Name of log file not specified. " +
+                                "Please specify it using traceLogFilename parameter");
+                    }
+                    Tracer.getInstance().setOutputFilename(filename);
+                }
+                Tracer.getInstance().setOutputMode(mode);
+            }
+
+            // add test listeners
+            testRunResult.addListener(resultPrinter);
+            // add all custom listeners
+            for (TestListener listener : mTestListeners) {
+                testRunResult.addListener(listener);
+            }
+
+            // run tests for realz!
+            for (TestCase testCase : testCases) {
+                prepareTestCase(testCase);
+                testCase.run(testRunResult);
+            }
+        } catch (Throwable t) {
+            // catch all exceptions so a more verbose error message can be outputted
+            resultPrinter.printUnexpectedError(t);
+            testRunOutput.putString("shortMsg", t.getMessage());
+        } finally {
+            long runTime = SystemClock.uptimeMillis() - startTime;
+            resultPrinter.print(testRunResult, runTime, testRunOutput);
+            automationWrapper.disconnect();
+            automationWrapper.setRunAsMonkey(false);
+            mHandlerThread.quit();
+        }
+    }
+
+    // copy & pasted from com.android.commands.am.Am
+    private class FakeInstrumentationWatcher implements IInstrumentationWatcher {
+
+        private final boolean mRawMode = true;
+
+        @Override
+        public IBinder asBinder() {
+            throw new UnsupportedOperationException("I'm just a fake!");
+        }
+
+        @Override
+        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.print(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println("INSTRUMENTATION_STATUS: " + key + "="
+                                    + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
+                }
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.println(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println("INSTRUMENTATION_RESULT: " + key + "="
+                                    + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
+                }
+                notifyAll();
+            }
+        }
+    }
+
+    private interface ResultReporter extends TestListener {
+        public void print(TestResult result, long runTime, Bundle testOutput);
+        public void printUnexpectedError(Throwable t);
+    }
+
+    // Copy & pasted from InstrumentationTestRunner.WatcherResultPrinter
+    private class WatcherResultPrinter implements ResultReporter {
+
+        private static final String REPORT_KEY_NUM_TOTAL = "numtests";
+        private static final String REPORT_KEY_NAME_CLASS = "class";
+        private static final String REPORT_KEY_NUM_CURRENT = "current";
+        private static final String REPORT_KEY_NAME_TEST = "test";
+        private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations";
+        private static final String REPORT_VALUE_ID = "UiAutomatorTestRunner";
+        private static final String REPORT_KEY_STACK = "stack";
+
+        private static final int REPORT_VALUE_RESULT_START = 1;
+        private static final int REPORT_VALUE_RESULT_ERROR = -1;
+        private static final int REPORT_VALUE_RESULT_FAILURE = -2;
+
+        private final Bundle mResultTemplate;
+        Bundle mTestResult;
+        int mTestNum = 0;
+        int mTestResultCode = 0;
+        String mTestClass = null;
+
+        private final SimpleResultPrinter mPrinter;
+        private final ByteArrayOutputStream mStream;
+        private final PrintStream mWriter;
+
+        public WatcherResultPrinter(int numTests) {
+            mResultTemplate = new Bundle();
+            mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
+            mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests);
+
+            mStream = new ByteArrayOutputStream();
+            mWriter = new PrintStream(mStream);
+            mPrinter = new SimpleResultPrinter(mWriter, false);
+        }
+
+        /**
+         * send a status for the start of a each test, so long tests can be seen
+         * as "running"
+         */
+        @Override
+        public void startTest(Test test) {
+            String testClass = test.getClass().getName();
+            String testName = ((TestCase) test).getName();
+            mTestResult = new Bundle(mResultTemplate);
+            mTestResult.putString(REPORT_KEY_NAME_CLASS, testClass);
+            mTestResult.putString(REPORT_KEY_NAME_TEST, testName);
+            mTestResult.putInt(REPORT_KEY_NUM_CURRENT, ++mTestNum);
+            // pretty printing
+            if (testClass != null && !testClass.equals(mTestClass)) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                        String.format("\n%s:", testClass));
+                mTestClass = testClass;
+            } else {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "");
+            }
+
+            Method testMethod = null;
+            try {
+                testMethod = test.getClass().getMethod(testName);
+                // Report total number of iterations, if test is repetitive
+                if (testMethod.isAnnotationPresent(RepetitiveTest.class)) {
+                    int numIterations = testMethod.getAnnotation(RepetitiveTest.class)
+                            .numIterations();
+                    mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations);
+                }
+            } catch (NoSuchMethodException e) {
+                // ignore- the test with given name does not exist. Will be
+                // handled during test
+                // execution
+            }
+
+            mAutomationSupport.sendStatus(REPORT_VALUE_RESULT_START, mTestResult);
+            mTestResultCode = 0;
+
+            mPrinter.startTest(test);
+        }
+
+        @Override
+        public void addError(Test test, Throwable t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_ERROR;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nError in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addError(test, t);
+        }
+
+        @Override
+        public void addFailure(Test test, AssertionFailedError t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_FAILURE;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nFailure in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addFailure(test, t);
+        }
+
+        @Override
+        public void endTest(Test test) {
+            if (mTestResultCode == 0) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ".");
+            }
+            mAutomationSupport.sendStatus(mTestResultCode, mTestResult);
+
+            mPrinter.endTest(test);
+        }
+
+        @Override
+        public void print(TestResult result, long runTime, Bundle testOutput) {
+            mPrinter.print(result, runTime, testOutput);
+            testOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                  String.format("\nTest results for %s=%s",
+                  getClass().getSimpleName(),
+                  mStream.toString()));
+            mWriter.close();
+            mAutomationSupport.sendStatus(Activity.RESULT_OK, testOutput);
+        }
+
+        @Override
+        public void printUnexpectedError(Throwable t) {
+            mWriter.println(String.format("Test run aborted due to unexpected exception: %s",
+                    t.getMessage()));
+            t.printStackTrace(mWriter);
+        }
+    }
+
+    /**
+     * Class that produces the same output as JUnit when running from command line. Can be
+     * used when default UiAutomator output is too verbose.
+     */
+    private class SimpleResultPrinter extends ResultPrinter implements ResultReporter {
+        private final boolean mFullOutput;
+        public SimpleResultPrinter(PrintStream writer, boolean fullOutput) {
+            super(writer);
+            mFullOutput = fullOutput;
+        }
+
+        @Override
+        public void print(TestResult result, long runTime, Bundle testOutput) {
+            printHeader(runTime);
+            if (mFullOutput) {
+                printErrors(result);
+                printFailures(result);
+            }
+            printFooter(result);
+        }
+
+        @Override
+        public void printUnexpectedError(Throwable t) {
+            if (mFullOutput) {
+                getWriter().printf("Test run aborted due to unexpected exeption: %s",
+                        t.getMessage());
+                t.printStackTrace(getWriter());
+            }
+        }
+    }
+
+    protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) {
+        return new TestCaseCollector(classLoader, getTestCaseFilter());
+    }
+
+    /**
+     * Returns an object which determines if the class and its methods should be
+     * accepted into the test suite.
+     * @return
+     */
+    public UiAutomatorTestCaseFilter getTestCaseFilter() {
+        return new UiAutomatorTestCaseFilter();
+    }
+
+    protected void addTestListener(TestListener listener) {
+        if (!mTestListeners.contains(listener)) {
+            mTestListeners.add(listener);
+        }
+    }
+
+    protected void removeTestListener(TestListener listener) {
+        mTestListeners.remove(listener);
+    }
+
+    /**
+     * subclass may override this method to perform further preparation
+     *
+     * @param testCase
+     */
+    protected void prepareTestCase(TestCase testCase) {
+        ((UiAutomatorTestCase)testCase).setAutomationSupport(mAutomationSupport);
+        ((UiAutomatorTestCase)testCase).setUiDevice(mUiDevice);
+        ((UiAutomatorTestCase)testCase).setParams(mParams);
+    }
+}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6b4db10..bcd8fb4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -44,7 +44,10 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.hardware.display.DisplayManagerGlobal;
+import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.LinkProperties;
+import android.net.Network;
 import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.net.Uri;
@@ -839,7 +842,13 @@
         }
 
         public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
-            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+            final Network network = ConnectivityManager.getProcessDefaultNetwork();
+            if (network != null) {
+                Proxy.setHttpProxySystemProperty(
+                        ConnectivityManager.from(getSystemContext()).getDefaultProxy());
+            } else {
+                Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+            }
         }
 
         public void processInBackground() {
@@ -4430,7 +4439,7 @@
             // crash if we can't get it.
             IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
             try {
-                ProxyInfo proxyInfo = service.getProxy();
+                final ProxyInfo proxyInfo = service.getDefaultProxy();
                 Proxy.setHttpProxySystemProperty(proxyInfo);
             } catch (RemoteException e) {}
         }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 3c30404..ad2b61f 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1217,8 +1217,10 @@
     public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent) {
         final String oldReferrer = activity.mReferrer;
         try {
-            activity.mReferrer = intent.mReferrer;
-            callActivityOnNewIntent(activity, new Intent(intent));
+            if (intent != null) {
+                activity.mReferrer = intent.mReferrer;
+            }
+            callActivityOnNewIntent(activity, intent != null ? new Intent(intent) : null);
         } finally {
             activity.mReferrer = oldReferrer;
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9e8a793..5afef80 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3771,8 +3771,24 @@
         }
 
         private RemoteViews makeBigContentView() {
+
+            // Replace mLargeIcon with mBigLargeIcon if mBigLargeIconSet
+            // This covers the following cases:
+            //   1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides
+            //          mLargeIcon
+            //   2. !mBigLargeIconSet -> mLargeIcon applies
+            Bitmap oldLargeIcon = null;
+            if (mBigLargeIconSet) {
+                oldLargeIcon = mBuilder.mLargeIcon;
+                mBuilder.mLargeIcon = mBigLargeIcon;
+            }
+
             RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
 
+            if (mBigLargeIconSet) {
+                mBuilder.mLargeIcon = oldLargeIcon;
+            }
+
             contentView.setImageViewBitmap(R.id.big_picture, mPicture);
 
             applyTopPadding(contentView);
@@ -3803,6 +3819,7 @@
             super.restoreFromExtras(extras);
 
             if (extras.containsKey(EXTRA_LARGE_ICON_BIG)) {
+                mBigLargeIconSet = true;
                 mBigLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON_BIG);
             }
             mPicture = extras.getParcelable(EXTRA_PICTURE);
@@ -4098,7 +4115,7 @@
      *
      * Unlike the other styles provided here, MediaStyle can also modify the standard-size
      * {@link Notification#contentView}; by providing action indices to
-     * {@link #setShowActionsInCompactView(int...)} you can promote up to 2 actions to be displayed
+     * {@link #setShowActionsInCompactView(int...)} you can promote up to 3 actions to be displayed
      * in the standard view alongside the usual content.
      *
      * Notifications created with MediaStyle will have their category set to
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index a86677c..7cdcc2c 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -502,7 +502,7 @@
      * @return Cached value of the characteristic
      */
     public String getStringValue(int offset) {
-        if (offset > mValue.length) return null;
+        if (mValue == null || offset > mValue.length) return null;
         byte[] strBytes = new byte[mValue.length - offset];
         for (int i=0; i != (mValue.length-offset); ++i) strBytes[i] = mValue[offset+i];
         return new String(strBytes);
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 546a50e..25d9aa9 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -229,7 +229,6 @@
     private ServiceListener mServiceListener;
     private IBluetoothHeadset mService;
     private BluetoothAdapter mAdapter;
-    private boolean mIsClosed;
 
     final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
             new IBluetoothStateChangeCallback.Stub() {
@@ -260,7 +259,6 @@
         mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mIsClosed = false;
 
         IBluetoothManager mgr = mAdapter.getBluetoothManager();
         if (mgr != null) {
@@ -314,7 +312,7 @@
                 Log.e(TAG,"",e);
             }
         }
-        mIsClosed = true;
+        mServiceListener = null;
         doUnbind();
     }
 
@@ -983,9 +981,6 @@
                     if (mServiceListener != null) {
                         mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
                     }
-                    if (mIsClosed){
-                        mServiceListener = null;
-                    }
                     break;
                 }
             }
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 360f308..0cff4c0 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -286,10 +286,12 @@
             final String original = setCallingPackage(callingPkg);
             try {
                 ContentProviderResult[] results = ContentProvider.this.applyBatch(operations);
-                for (int i = 0; i < results.length ; i++) {
-                    if (userIds[i] != UserHandle.USER_CURRENT) {
-                        // Adding the userId to the uri.
-                        results[i] = new ContentProviderResult(results[i], userIds[i]);
+                if (results != null) {
+                    for (int i = 0; i < results.length ; i++) {
+                        if (userIds[i] != UserHandle.USER_CURRENT) {
+                            // Adding the userId to the uri.
+                            results[i] = new ContentProviderResult(results[i], userIds[i]);
+                        }
                     }
                 }
                 return results;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index de7fbab..5ebbf16 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4391,7 +4391,7 @@
                 // scheme
                 else if (uri.startsWith("scheme=", i)) {
                     if (inSelector) {
-                        intent.mData = Uri.parse(value);
+                        intent.mData = Uri.parse(value + ":");
                     } else {
                         scheme = value;
                     }
@@ -4461,14 +4461,19 @@
                             String authority = null;
                             intent.mPackage = data.substring(14, end);
                             int newEnd;
-                            if (end < data.length() && (newEnd=data.indexOf('/', end+1)) >= 0) {
-                                // Found a scheme, remember it.
-                                scheme = data.substring(end+1, newEnd);
-                                end = newEnd;
-                                if (end < data.length() && (newEnd=data.indexOf('/', end+1)) >= 0) {
-                                    // Found a authority, remember it.
-                                    authority = data.substring(end+1, newEnd);
+                            if ((end+1) < data.length()) {
+                                if ((newEnd=data.indexOf('/', end+1)) >= 0) {
+                                    // Found a scheme, remember it.
+                                    scheme = data.substring(end+1, newEnd);
                                     end = newEnd;
+                                    if (end < data.length() && (newEnd=data.indexOf('/', end+1)) >= 0) {
+                                        // Found a authority, remember it.
+                                        authority = data.substring(end+1, newEnd);
+                                        end = newEnd;
+                                    }
+                                } else {
+                                    // All we have is a scheme.
+                                    scheme = data.substring(end+1);
                                 }
                             }
                             if (scheme == null) {
@@ -7355,7 +7360,7 @@
 
         toUriInner(frag, scheme, defAction, defPackage, flags);
         if (mSelector != null) {
-            uri.append("SEL;");
+            frag.append("SEL;");
             // Note that for now we are not going to try to handle the
             // data part; not clear how to represent this as a URI, and
             // not much utility in it.
diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
index 64c532b..b160d2a 100644
--- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
@@ -22,6 +22,8 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
 import android.view.Surface;
 
 import java.util.Collection;
@@ -57,11 +59,11 @@
      */
     private static class ConfigureHolder {
         public final ConditionVariable condition;
-        public final Collection<Surface> surfaces;
+        public final Collection<Pair<Surface, Size>> surfaces;
         public final CaptureCollector collector;
 
-        public ConfigureHolder(ConditionVariable condition, Collection<Surface> surfaces,
-                               CaptureCollector collector) {
+        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
+                Size>> surfaces, CaptureCollector collector) {
             this.condition = condition;
             this.surfaces = surfaces;
             this.collector = collector;
@@ -202,10 +204,12 @@
      * Configure the GL renderer for the given set of output surfaces, and block until
      * this configuration has been applied.
      *
-     * @param surfaces a collection of {@link android.view.Surface}s to configure.
+     * @param surfaces a collection of pairs of {@link android.view.Surface}s and their
+     *                 corresponding sizes to configure.
      * @param collector a {@link CaptureCollector} to retrieve requests from.
      */
-    public void setConfigurationAndWait(Collection<Surface> surfaces, CaptureCollector collector) {
+    public void setConfigurationAndWait(Collection<Pair<Surface, Size>> surfaces,
+                                        CaptureCollector collector) {
         checkNotNull(collector, "collector must not be null");
         Handler handler = mGLHandlerThread.getHandler();
 
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 3a976ba..3043d13 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -24,7 +24,6 @@
 import android.hardware.camera2.impl.CameraDeviceImpl;
 import android.hardware.camera2.impl.CaptureResultExtras;
 import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.params.StreamConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.ArrayUtils;
 import android.hardware.camera2.utils.CameraBinderDecorator;
@@ -36,6 +35,7 @@
 import android.os.HandlerThread;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Size;
 import android.view.Surface;
 
@@ -78,6 +78,15 @@
     private final Handler mResultHandler;
     private static final int ILLEGAL_VALUE = -1;
 
+    // Keep up to date with values in hardware/libhardware/include/hardware/gralloc.h
+    private static final int GRALLOC_USAGE_RENDERSCRIPT = 0x00100000;
+    private static final int GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003;
+    private static final int GRALLOC_USAGE_HW_TEXTURE = 0x00000100;
+    private static final int GRALLOC_USAGE_HW_COMPOSER = 0x00000800;
+    private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
+
+    private static final int MAX_DIMEN_FOR_ROUNDING = 1080; // maximum allowed width for rounding
+
     private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) {
         if (holder == null) {
             return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
@@ -276,6 +285,7 @@
      *          on success.
      */
     public int configureOutputs(List<Surface> outputs) {
+        List<Pair<Surface, Size>> sizedSurfaces = new ArrayList<>();
         if (outputs != null) {
             for (Surface output : outputs) {
                 if (output == null) {
@@ -289,16 +299,25 @@
                 try {
                     Size s = getSurfaceSize(output);
                     int surfaceType = detectSurfaceType(output);
-                    Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
+                    int usageFlags = detectSurfaceUsageFlags(output);
 
+                    // Keep up to date with allowed consumer types in
+                    // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+                    int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT;
+                    int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN |
+                            GRALLOC_USAGE_HW_COMPOSER;
+                    boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 &&
+                            (usageFlags & allowedFlags) != 0);
+
+                    Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
                     if (sizes == null) {
                         // WAR: Override default format to IMPLEMENTATION_DEFINED for b/9487482
                         if ((surfaceType >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
                             surfaceType <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
 
-                            // YUV_420_888 is always present in LEGACY for all IMPLEMENTATION_DEFINED
-                            // output sizes, and is publicly visible in the API (i.e.
-                            // {@code #getOutputSizes} works here).
+                            // YUV_420_888 is always present in LEGACY for all
+                            // IMPLEMENTATION_DEFINED output sizes, and is publicly visible in the
+                            // API (i.e. {@code #getOutputSizes} works here).
                             sizes = streamConfigurations.getOutputSizes(ImageFormat.YUV_420_888);
                         } else if (surfaceType == LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB) {
                             sizes = streamConfigurations.getOutputSizes(ImageFormat.JPEG);
@@ -306,12 +325,18 @@
                     }
 
                     if (!ArrayUtils.contains(sizes, s)) {
-                        String reason = (sizes == null) ? "format is invalid." :
-                                ("size not in valid set: " + Arrays.toString(sizes));
-                        Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format 0x%x is"
-                                + " not valid, %s", s.getWidth(), s.getHeight(), surfaceType,
-                                reason));
-                        return BAD_VALUE;
+                        if (flexibleConsumer && (s = findClosestSize(s, sizes)) != null) {
+                            sizedSurfaces.add(new Pair<>(output, s));
+                        } else {
+                            String reason = (sizes == null) ? "format is invalid." :
+                                    ("size not in valid set: " + Arrays.toString(sizes));
+                            Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format " +
+                                    "0x%x is not valid, %s", s.getWidth(), s.getHeight(),
+                                    surfaceType, reason));
+                            return BAD_VALUE;
+                        }
+                    } else {
+                        sizedSurfaces.add(new Pair<>(output, s));
                     }
                 } catch (BufferQueueAbandonedException e) {
                     Log.e(TAG, "Surface bufferqueue is abandoned, cannot configure as output: ", e);
@@ -323,7 +348,7 @@
 
         boolean success = false;
         if (mDeviceState.setConfiguring()) {
-            mRequestThreadManager.configure(outputs);
+            mRequestThreadManager.configure(sizedSurfaces);
             success = mDeviceState.setIdle();
         }
 
@@ -473,6 +498,31 @@
         }
     }
 
+    static long findEuclidDistSquare(Size a, Size b) {
+        long d0 = a.getWidth() - b.getWidth();
+        long d1 = a.getHeight() - b.getHeight();
+        return d0 * d0 + d1 * d1;
+    }
+
+    // Keep up to date with rounding behavior in
+    // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+    static Size findClosestSize(Size size, Size[] supportedSizes) {
+        if (size == null || supportedSizes == null) {
+            return null;
+        }
+        Size bestSize = null;
+        for (Size s : supportedSizes) {
+            if (s.equals(size)) {
+                return size;
+            } else if (s.getWidth() <= MAX_DIMEN_FOR_ROUNDING && (bestSize == null ||
+                    LegacyCameraDevice.findEuclidDistSquare(size, s) <
+                    LegacyCameraDevice.findEuclidDistSquare(bestSize, s))) {
+                bestSize = s;
+            }
+        }
+        return bestSize;
+    }
+
     /**
      * Query the surface for its currently configured default buffer size.
      * @param surface a non-{@code null} {@code Surface}
@@ -490,6 +540,11 @@
         return new Size(dimens[0], dimens[1]);
     }
 
+    static int detectSurfaceUsageFlags(Surface surface) {
+        checkNotNull(surface);
+        return nativeDetectSurfaceUsageFlags(surface);
+    }
+
     static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException {
         checkNotNull(surface);
         return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
@@ -608,5 +663,7 @@
 
     private static native int nativeSetNextTimestamp(Surface surface, long timestamp);
 
+    private static native int nativeDetectSurfaceUsageFlags(Surface surface);
+
     static native int nativeGetJpegFooterSize();
 }
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 35deb71..6535a4e 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -41,6 +41,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -116,9 +117,10 @@
      */
     private static class ConfigureHolder {
         public final ConditionVariable condition;
-        public final Collection<Surface> surfaces;
+        public final Collection<Pair<Surface, Size>> surfaces;
 
-        public ConfigureHolder(ConditionVariable condition, Collection<Surface> surfaces) {
+        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
+                Size>> surfaces) {
             this.condition = condition;
             this.surfaces = surfaces;
         }
@@ -317,7 +319,7 @@
         startPreview();
     }
 
-    private void configureOutputs(Collection<Surface> outputs) {
+    private void configureOutputs(Collection<Pair<Surface, Size>> outputs) {
         if (DEBUG) {
             String outputsStr = outputs == null ? "null" : (outputs.size() + " surfaces");
             Log.d(TAG, "configureOutputs with " + outputsStr);
@@ -346,10 +348,15 @@
         mJpegSurfaceIds.clear();
         mPreviewTexture = null;
 
+        List<Size> previewOutputSizes = new ArrayList<>();
+        List<Size> callbackOutputSizes = new ArrayList<>();
+
         int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
         int orientation = mCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
         if (outputs != null) {
-            for (Surface s : outputs) {
+            for (Pair<Surface, Size> outPair : outputs) {
+                Surface s = outPair.first;
+                Size outSize = outPair.second;
                 try {
                     int format = LegacyCameraDevice.detectSurfaceType(s);
                     LegacyCameraDevice.setSurfaceOrientation(s, facing, orientation);
@@ -362,9 +369,11 @@
                             }
                             mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s));
                             mCallbackOutputs.add(s);
+                            callbackOutputSizes.add(outSize);
                             break;
                         default:
                             mPreviewOutputs.add(s);
+                            previewOutputSizes.add(outSize);
                             break;
                     }
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
@@ -391,18 +400,9 @@
         mParams.setPreviewFpsRange(bestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
                 bestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
 
-        if (mPreviewOutputs.size() > 0) {
-            List<Size> outputSizes = new ArrayList<>(outputs.size());
-            for (Surface s : mPreviewOutputs) {
-                try {
-                    Size size = LegacyCameraDevice.getSurfaceSize(s);
-                    outputSizes.add(size);
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, skipping...", e);
-                }
-            }
+        if (previewOutputSizes.size() > 0) {
 
-            Size largestOutput = SizeAreaComparator.findLargestByArea(outputSizes);
+            Size largestOutput = SizeAreaComparator.findLargestByArea(previewOutputSizes);
 
             // Find largest jpeg dimension - assume to have the same aspect ratio as sensor.
             Size largestJpegDimen = ParameterUtils.getLargestSupportedJpegSizeByArea(mParams);
@@ -439,7 +439,8 @@
             }
         }
 
-        Size smallestSupportedJpegSize = calculatePictureSize(mCallbackOutputs, mParams);
+        Size smallestSupportedJpegSize = calculatePictureSize(mCallbackOutputs,
+                callbackOutputSizes, mParams);
         if (smallestSupportedJpegSize != null) {
             /*
              * Set takePicture size to the smallest supported JPEG size large enough
@@ -457,7 +458,12 @@
             mGLThreadManager.start();
         }
         mGLThreadManager.waitUntilStarted();
-        mGLThreadManager.setConfigurationAndWait(mPreviewOutputs, mCaptureCollector);
+        List<Pair<Surface, Size>> previews = new ArrayList<>();
+        Iterator<Size> previewSizeIter = previewOutputSizes.iterator();
+        for (Surface p : mPreviewOutputs) {
+            previews.add(new Pair<>(p, previewSizeIter.next()));
+        }
+        mGLThreadManager.setConfigurationAndWait(previews, mCaptureCollector);
         mGLThreadManager.allowNewFrames();
         mPreviewTexture = mGLThreadManager.getCurrentSurfaceTexture();
         if (mPreviewTexture != null) {
@@ -499,26 +505,25 @@
      *          {@code null} if the {@code callbackOutputs} did not have any {@code JPEG}
      *          surfaces.
      */
-    private Size calculatePictureSize(
-            Collection<Surface> callbackOutputs, Camera.Parameters params) {
+    private Size calculatePictureSize( List<Surface> callbackOutputs,
+                                       List<Size> callbackSizes, Camera.Parameters params) {
         /*
          * Find the largest JPEG size (if any), from the configured outputs:
          * - the api1 picture size should be set to the smallest legal size that's at least as large
          *   as the largest configured JPEG size
          */
-        List<Size> configuredJpegSizes = new ArrayList<Size>();
+        if (callbackOutputs.size() != callbackSizes.size()) {
+            throw new IllegalStateException("Input collections must be same length");
+        }
+        List<Size> configuredJpegSizes = new ArrayList<>();
+        Iterator<Size> sizeIterator = callbackSizes.iterator();
         for (Surface callbackSurface : callbackOutputs) {
-            try {
-
+            Size jpegSize = sizeIterator.next();
                 if (!LegacyCameraDevice.containsSurfaceId(callbackSurface, mJpegSurfaceIds)) {
                     continue; // Ignore non-JPEG callback formats
                 }
 
-                Size jpegSize = LegacyCameraDevice.getSurfaceSize(callbackSurface);
                 configuredJpegSizes.add(jpegSize);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
         }
         if (!configuredJpegSizes.isEmpty()) {
             /*
@@ -994,7 +999,7 @@
      *
      * @param outputs a {@link java.util.Collection} of outputs to configure.
      */
-    public void configure(Collection<Surface> outputs) {
+    public void configure(Collection<Pair<Surface, Size>> outputs) {
         Handler handler = mRequestThread.waitAndGetHandler();
         final ConditionVariable condition = new ConditionVariable(/*closed*/false);
         ConfigureHolder holder = new ConfigureHolder(condition, outputs);
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index c0d1d5e..a0a0716 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -58,6 +58,11 @@
     private static final int GLES_VERSION = 2;
     private static final int PBUFFER_PIXEL_BYTES = 4;
 
+    private static final int FLIP_TYPE_NONE = 0;
+    private static final int FLIP_TYPE_HORIZONTAL = 1;
+    private static final int FLIP_TYPE_VERTICAL = 2;
+    private static final int FLIP_TYPE_BOTH = FLIP_TYPE_HORIZONTAL | FLIP_TYPE_VERTICAL;
+
     private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
     private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
     private EGLConfig mConfigs;
@@ -82,8 +87,8 @@
     private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
     private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
 
-    // Sampling is mirrored across the vertical axis to undo horizontal flip from the front camera
-    private static final float[] sFrontCameraTriangleVertices = {
+    // Sampling is mirrored across the horizontal axis
+    private static final float[] sHorizontalFlipTriangleVertices = {
             // X, Y, Z, U, V
             -1.0f, -1.0f, 0, 1.f, 0.f,
             1.0f, -1.0f, 0, 0.f, 0.f,
@@ -91,8 +96,26 @@
             1.0f,  1.0f, 0, 0.f, 1.f,
     };
 
+    // Sampling is mirrored across the vertical axis
+    private static final float[] sVerticalFlipTriangleVertices = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 0.f, 1.f,
+            1.0f, -1.0f, 0, 1.f, 1.f,
+            -1.0f,  1.0f, 0, 0.f, 0.f,
+            1.0f,  1.0f, 0, 1.f, 0.f,
+    };
+
+    // Sampling is mirrored across the both axes
+    private static final float[] sBothFlipTriangleVertices = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 1.f, 1.f,
+            1.0f, -1.0f, 0, 0.f, 1.f,
+            -1.0f,  1.0f, 0, 1.f, 0.f,
+            1.0f,  1.0f, 0, 0.f, 0.f,
+    };
+
     // Sampling is 1:1 for a straight copy for the back camera
-    private static final float[] sBackCameraTriangleVertices = {
+    private static final float[] sRegularTriangleVertices = {
             // X, Y, Z, U, V
             -1.0f, -1.0f, 0, 0.f, 0.f,
             1.0f, -1.0f, 0, 1.f, 0.f,
@@ -100,7 +123,11 @@
             1.0f,  1.0f, 0, 1.f, 1.f,
     };
 
-    private FloatBuffer mTriangleVertices;
+    private FloatBuffer mRegularTriangleVertices;
+    private FloatBuffer mHorizontalFlipTriangleVertices;
+    private FloatBuffer mVerticalFlipTriangleVertices;
+    private FloatBuffer mBothFlipTriangleVertices;
+    private final int mFacing;
 
     /**
      * As used in this file, this vertex shader maps a unit square to the view, and
@@ -148,15 +175,27 @@
     private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf";
 
     public SurfaceTextureRenderer(int facing) {
-        if (facing == CameraCharacteristics.LENS_FACING_BACK) {
-            mTriangleVertices = ByteBuffer.allocateDirect(sBackCameraTriangleVertices.length *
-                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-            mTriangleVertices.put(sBackCameraTriangleVertices).position(0);
-        } else {
-            mTriangleVertices = ByteBuffer.allocateDirect(sFrontCameraTriangleVertices.length *
-                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-            mTriangleVertices.put(sFrontCameraTriangleVertices).position(0);
-        }
+        mFacing = facing;
+
+        mRegularTriangleVertices = ByteBuffer.allocateDirect(sRegularTriangleVertices.length *
+                FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mRegularTriangleVertices.put(sRegularTriangleVertices).position(0);
+
+        mHorizontalFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sHorizontalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mHorizontalFlipTriangleVertices.put(sHorizontalFlipTriangleVertices).position(0);
+
+        mVerticalFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sVerticalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mVerticalFlipTriangleVertices.put(sVerticalFlipTriangleVertices).position(0);
+
+        mBothFlipTriangleVertices = ByteBuffer.allocateDirect(
+                sBothFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mBothFlipTriangleVertices.put(sBothFlipTriangleVertices).position(0);
+
         Matrix.setIdentityM(mSTMatrix, 0);
     }
 
@@ -209,7 +248,7 @@
         return program;
     }
 
-    private void drawFrame(SurfaceTexture st, int width, int height) {
+    private void drawFrame(SurfaceTexture st, int width, int height, int flipType) {
         checkGlError("onDrawFrame start");
         st.getTransformMatrix(mSTMatrix);
 
@@ -266,16 +305,32 @@
         GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
         GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
 
-        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+        FloatBuffer triangleVertices;
+        switch(flipType) {
+            case FLIP_TYPE_HORIZONTAL:
+                triangleVertices = mHorizontalFlipTriangleVertices;
+                break;
+            case FLIP_TYPE_VERTICAL:
+                triangleVertices = mVerticalFlipTriangleVertices;
+                break;
+            case FLIP_TYPE_BOTH:
+                triangleVertices = mBothFlipTriangleVertices;
+                break;
+            default:
+                triangleVertices = mRegularTriangleVertices;
+                break;
+        }
+
+        triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
         GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
         checkGlError("glVertexAttribPointer maPosition");
         GLES20.glEnableVertexAttribArray(maPositionHandle);
         checkGlError("glEnableVertexAttribArray maPositionHandle");
 
-        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+        triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
         GLES20.glVertexAttribPointer(maTextureHandle, VERTEX_UV_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
         checkGlError("glVertexAttribPointer maTextureHandle");
         GLES20.glEnableVertexAttribArray(maTextureHandle);
         checkGlError("glEnableVertexAttribArray maTextureHandle");
@@ -397,16 +452,9 @@
                 EGL14.EGL_NONE
         };
         for (EGLSurfaceHolder holder : surfaces) {
-            try {
-                Size size = LegacyCameraDevice.getSurfaceSize(holder.surface);
-                holder.width = size.getWidth();
-                holder.height = size.getHeight();
-                holder.eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs,
-                        holder.surface, surfaceAttribs, /*offset*/ 0);
-                checkEglError("eglCreateWindowSurface");
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
+            holder.eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs,
+                    holder.surface, surfaceAttribs, /*offset*/ 0);
+            checkEglError("eglCreateWindowSurface");
         }
     }
 
@@ -417,24 +465,17 @@
 
         int maxLength = 0;
         for (EGLSurfaceHolder holder : surfaces) {
-            try {
-                Size size = LegacyCameraDevice.getSurfaceSize(holder.surface);
-                int length = size.getWidth() * size.getHeight();
-                // Find max surface size, ensure PBuffer can hold this many pixels
-                maxLength = (length > maxLength) ? length : maxLength;
-                int[] surfaceAttribs = {
-                        EGL14.EGL_WIDTH, size.getWidth(),
-                        EGL14.EGL_HEIGHT, size.getHeight(),
-                        EGL14.EGL_NONE
-                };
-                holder.width = size.getWidth();
-                holder.height = size.getHeight();
-                holder.eglSurface =
-                        EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0);
-                checkEglError("eglCreatePbufferSurface");
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
+            int length = holder.width * holder.height;
+            // Find max surface size, ensure PBuffer can hold this many pixels
+            maxLength = (length > maxLength) ? length : maxLength;
+            int[] surfaceAttribs = {
+                    EGL14.EGL_WIDTH, holder.width,
+                    EGL14.EGL_HEIGHT, holder.height,
+                    EGL14.EGL_NONE
+            };
+            holder.eglSurface =
+                    EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0);
+            checkEglError("eglCreatePbufferSurface");
         }
         mPBufferPixels = ByteBuffer.allocateDirect(maxLength * PBUFFER_PIXEL_BYTES)
                 .order(ByteOrder.nativeOrder());
@@ -569,7 +610,7 @@
      *
      * @param surfaces a {@link Collection} of surfaces.
      */
-    public void configureSurfaces(Collection<Surface> surfaces) {
+    public void configureSurfaces(Collection<Pair<Surface, Size>> surfaces) {
         releaseEGLContext();
 
         if (surfaces == null || surfaces.size() == 0) {
@@ -577,18 +618,20 @@
             return;
         }
 
-        for (Surface s : surfaces) {
+        for (Pair<Surface, Size> p : surfaces) {
+            Surface s = p.first;
+            Size surfaceSize = p.second;
             // If pixel conversions aren't handled by egl, use a pbuffer
             try {
+                EGLSurfaceHolder holder = new EGLSurfaceHolder();
+                holder.surface = s;
+                holder.width = surfaceSize.getWidth();
+                holder.height = surfaceSize.getHeight();
                 if (LegacyCameraDevice.needsConversion(s)) {
                     // Always override to YV12 output for YUV surface formats.
                     LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12);
-                    EGLSurfaceHolder holder = new EGLSurfaceHolder();
-                    holder.surface = s;
                     mConversionSurfaces.add(holder);
                 } else {
-                    EGLSurfaceHolder holder = new EGLSurfaceHolder();
-                    holder.surface = s;
                     mSurfaces.add(holder);
                 }
             } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
@@ -672,12 +715,15 @@
         List<Long> targetSurfaceIds = LegacyCameraDevice.getSurfaceIds(targetSurfaces);
         for (EGLSurfaceHolder holder : mSurfaces) {
             if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
-                makeCurrent(holder.eglSurface);
-                try {
+                try{
                     LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
                             holder.height);
+                    makeCurrent(holder.eglSurface);
+
                     LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
-                    drawFrame(mSurfaceTexture, holder.width, holder.height);
+                    drawFrame(mSurfaceTexture, holder.width, holder.height,
+                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+                                    FLIP_TYPE_HORIZONTAL : FLIP_TYPE_NONE);
                     swapBuffers(holder.eglSurface);
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                     Log.w(TAG, "Surface abandoned, dropping frame. ", e);
@@ -687,7 +733,10 @@
         for (EGLSurfaceHolder holder : mConversionSurfaces) {
             if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
                 makeCurrent(holder.eglSurface);
-                drawFrame(mSurfaceTexture, holder.width, holder.height);
+                // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip
+                drawFrame(mSurfaceTexture, holder.width, holder.height,
+                        (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
+                                FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
                 mPBufferPixels.clear();
                 GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height,
                         GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels);
@@ -695,10 +744,11 @@
 
                 try {
                     int format = LegacyCameraDevice.detectSurfaceType(holder.surface);
+                    LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
+                            holder.height);
                     LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
                     LegacyCameraDevice.produceFrame(holder.surface, mPBufferPixels.array(),
                             holder.width, holder.height, format);
-                    swapBuffers(holder.eglSurface);
                 } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                     Log.w(TAG, "Surface abandoned, dropping frame. ", e);
                 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4215f20..17ee494 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -37,6 +37,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -100,7 +101,7 @@
 
     /**
      * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
-     * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
+     * historic {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
      *
      * @hide
      */
@@ -428,18 +429,6 @@
     public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
 
     /**
-     * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
-     * milliseconds.  This was introduced because IPv6 routes seem to take a
-     * moment to settle - trying network activity before the routes are adjusted
-     * can lead to packets using the wrong interface or having the wrong IP address.
-     * This delay is a bit crude, but in the future hopefully we will have kernel
-     * notifications letting us know when it's safe to use the new network.
-     *
-     * @hide
-     */
-    public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
-
-    /**
      * @hide
      */
     public final static int REQUEST_ID_UNSET = 0;
@@ -452,6 +441,13 @@
     public static final int NETID_UNSET = 0;
 
     private final IConnectivityManager mService;
+    /**
+     * A kludge to facilitate static access where a Context pointer isn't available, like in the
+     * case of the static set/getProcessDefaultNetwork methods and from the Network class.
+     * TODO: Remove this after deprecating the static methods in favor of non-static methods or
+     * methods that take a Context argument.
+     */
+    private static ConnectivityManager sInstance;
 
     private INetworkManagementService mNMService;
 
@@ -1295,9 +1291,15 @@
         if (b != null) {
             try {
                 ITelephony it = ITelephony.Stub.asInterface(b);
-                return it.getDataEnabled();
+                int subId = SubscriptionManager.getDefaultDataSubId();
+                Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
+                boolean retVal = it.getDataEnabled(subId);
+                Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
+                        + " retVal=" + retVal);
+                return retVal;
             } catch (RemoteException e) { }
         }
+        Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
         return false;
     }
 
@@ -1397,6 +1399,7 @@
      */
     public ConnectivityManager(IConnectivityManager service) {
         mService = checkNotNull(service, "missing IConnectivityManager");
+        sInstance = this;
     }
 
     /** {@hide} */
@@ -1419,6 +1422,18 @@
     }
 
     /**
+     * @deprecated - use getSystemService. This is a kludge to support static access in certain
+     *               situations where a Context pointer is unavailable.
+     * @hide
+     */
+    public static ConnectivityManager getInstance() {
+        if (sInstance == null) {
+            throw new IllegalStateException("No ConnectivityManager yet constructed");
+        }
+        return sInstance;
+    }
+
+    /**
      * Get the set of tetherable, available interfaces.  This list is limited by
      * device configuration and current interface existence.
      *
@@ -1749,20 +1764,26 @@
     }
 
     /**
-     * Get the HTTP proxy settings for the current default network.  Note that
-     * if a global proxy is set, it will override any per-network setting.
+     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
+     * otherwise if this process is bound to a {@link Network} using
+     * {@link #setProcessDefaultNetwork} then that {@code Network}'s proxy is returned, otherwise
+     * the default network's proxy is returned.
      *
      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
      *        HTTP proxy is active.
-     *
-     * <p>This method requires the call to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
-     * {@hide}
-     * @deprecated Deprecated in favor of {@link #getLinkProperties}
+     * @hide
      */
-    public ProxyInfo getProxy() {
+    public ProxyInfo getDefaultProxy() {
+        final Network network = getProcessDefaultNetwork();
+        if (network != null) {
+            final ProxyInfo globalProxy = getGlobalProxy();
+            if (globalProxy != null) return globalProxy;
+            final LinkProperties lp = getLinkProperties(network);
+            if (lp != null) return lp.getHttpProxy();
+            return null;
+        }
         try {
-            return mService.getProxy();
+            return mService.getDefaultProxy();
         } catch (RemoteException e) {
             return null;
         }
@@ -2475,6 +2496,9 @@
             return true;
         }
         if (NetworkUtils.bindProcessToNetwork(netId)) {
+            // Set HTTP proxy system properties to match network.
+            // TODO: Deprecate this static method and replace it with a non-static version.
+            Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
             // Must flush DNS cache as new network may have different DNS resolutions.
             InetAddress.clearDnsCache();
             // Must flush socket pool as idle sockets will be bound to previous network and may
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d9921a6..46af112 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -100,7 +100,7 @@
 
     void setGlobalProxy(in ProxyInfo p);
 
-    ProxyInfo getProxy();
+    ProxyInfo getDefaultProxy();
 
     void setDataDependency(int networkType, boolean met);
 
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
index a36203b..9464222 100644
--- a/core/java/android/net/LocalServerSocket.java
+++ b/core/java/android/net/LocalServerSocket.java
@@ -20,12 +20,8 @@
 import java.io.FileDescriptor;
 
 /**
- * non-standard class for creating inbound UNIX-domain socket
- * on the Android platform, this is created in the Linux non-filesystem
- * namespace.
- *
- * On simulator platforms, this may be created in a temporary directory on
- * the filesystem
+ * Non-standard class for creating an inbound UNIX-domain socket
+ * in the Linux abstract namespace.
  */
 public class LocalServerSocket {
     private final LocalSocketImpl impl;
@@ -35,7 +31,7 @@
     private static final int LISTEN_BACKLOG = 50;
 
     /**
-     * Crewates a new server socket listening at specified name.
+     * Creates a new server socket listening at specified name.
      * On the Android platform, the name is created in the Linux
      * abstract namespace (instead of on the filesystem).
      * 
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 4fa0593..5c12696 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -27,6 +27,7 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.MalformedURLException;
+import java.net.ProxySelector;
 import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketException;
@@ -244,16 +245,46 @@
      * @see java.net.URL#openConnection()
      */
     public URLConnection openConnection(URL url) throws IOException {
+        final ConnectivityManager cm = ConnectivityManager.getInstance();
+        // TODO: Should this be optimized to avoid fetching the global proxy for every request?
+        ProxyInfo proxyInfo = cm.getGlobalProxy();
+        if (proxyInfo == null) {
+            // TODO: Should this be optimized to avoid fetching LinkProperties for every request?
+            final LinkProperties lp = cm.getLinkProperties(this);
+            if (lp != null) proxyInfo = lp.getHttpProxy();
+        }
+        java.net.Proxy proxy = null;
+        if (proxyInfo != null) {
+            proxy = proxyInfo.makeProxy();
+        } else {
+            proxy = java.net.Proxy.NO_PROXY;
+        }
+        return openConnection(url, proxy);
+    }
+
+    /**
+     * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent
+     * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}.
+     *
+     * @param proxy the proxy through which the connection will be established.
+     * @return a {@code URLConnection} to the resource referred to by this URL.
+     * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS.
+     * @throws IllegalArgumentException if the argument proxy is null.
+     * @throws IOException if an error occurs while opening the connection.
+     * @see java.net.URL#openConnection()
+     * @hide
+     */
+    public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException {
+        if (proxy == null) throw new IllegalArgumentException("proxy is null");
         maybeInitHttpClient();
         String protocol = url.getProtocol();
         OkHttpClient client;
         // TODO: HttpHandler creates OkHttpClients that share the default ResponseCache.
         // Could this cause unexpected behavior?
-        // TODO: Should the network's proxy be specified?
         if (protocol.equals("http")) {
-            client = HttpHandler.createHttpOkHttpClient(null /* proxy */);
+            client = HttpHandler.createHttpOkHttpClient(proxy);
         } else if (protocol.equals("https")) {
-            client = HttpsHandler.createHttpsOkHttpClient(null /* proxy */);
+            client = HttpsHandler.createHttpsOkHttpClient(proxy);
         } else {
             // OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if
             // passed another protocol.
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
index 6ddd8b3..9b80e74 100644
--- a/core/java/android/net/NetworkFactory.java
+++ b/core/java/android/net/NetworkFactory.java
@@ -274,4 +274,12 @@
     protected void log(String s) {
         Log.d(LOG_TAG, s);
     }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter=").
+                append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=").
+                append(mNetworkRequests.size()).append("}");
+        return sb.toString();
+    }
 }
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index 7694420..a3cad77 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -260,7 +260,8 @@
         if (!Uri.EMPTY.equals(mPacFileUrl)) {
             sb.append("PAC Script: ");
             sb.append(mPacFileUrl);
-        } else if (mHost != null) {
+        }
+        if (mHost != null) {
             sb.append("[");
             sb.append(mHost);
             sb.append("] ");
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 9589aac..1b02141b9 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -329,7 +329,7 @@
      * @param key a String, or null
      * @param value a Boolean, or null
      */
-    void putBoolean(String key, boolean value) {
+    public void putBoolean(String key, boolean value) {
         unparcel();
         mMap.put(key, value);
     }
@@ -497,7 +497,7 @@
      * @param key a String, or null
      * @param value a boolean array object, or null
      */
-    void putBooleanArray(String key, boolean[] value) {
+    public void putBooleanArray(String key, boolean[] value) {
         unparcel();
         mMap.put(key, value);
     }
@@ -617,7 +617,7 @@
      * @param key a String
      * @return a boolean value
      */
-    boolean getBoolean(String key) {
+    public boolean getBoolean(String key) {
         unparcel();
         if (DEBUG) Log.d(TAG, "Getting boolean in "
                 + Integer.toHexString(System.identityHashCode(this)));
@@ -654,7 +654,7 @@
      * @param defaultValue Value to return if key does not exist
      * @return a boolean value
      */
-    boolean getBoolean(String key, boolean defaultValue) {
+    public boolean getBoolean(String key, boolean defaultValue) {
         unparcel();
         Object o = mMap.get(key);
         if (o == null) {
@@ -1072,7 +1072,7 @@
      * @param key a String, or null
      * @return a boolean[] value, or null
      */
-    boolean[] getBooleanArray(String key) {
+    public boolean[] getBooleanArray(String key) {
         unparcel();
         Object o = mMap.get(key);
         if (o == null) {
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index a9aa570..c5c5372 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -252,18 +252,6 @@
     }
 
     /**
-     * Inserts a Boolean value into the mapping of this Bundle, replacing
-     * any existing value for the given key.  Either key or value may be null.
-     *
-     * @param key a String, or null
-     * @param value a Boolean, or null
-     */
-    @Override
-    public void putBoolean(String key, boolean value) {
-        super.putBoolean(key, value);
-    }
-
-    /**
      * Inserts a byte value into the mapping of this Bundle, replacing
      * any existing value for the given key.
      *
@@ -460,18 +448,6 @@
     }
 
     /**
-     * Inserts a boolean array value into the mapping of this Bundle, replacing
-     * any existing value for the given key.  Either key or value may be null.
-     *
-     * @param key a String, or null
-     * @param value a boolean array object, or null
-     */
-    @Override
-    public void putBooleanArray(String key, boolean[] value) {
-        super.putBooleanArray(key, value);
-    }
-
-    /**
      * Inserts a byte array value into the mapping of this Bundle, replacing
      * any existing value for the given key.  Either key or value may be null.
      *
@@ -579,31 +555,6 @@
     }
 
     /**
-     * Returns the value associated with the given key, or false if
-     * no mapping of the desired type exists for the given key.
-     *
-     * @param key a String
-     * @return a boolean value
-     */
-    @Override
-    public boolean getBoolean(String key) {
-        return super.getBoolean(key);
-    }
-
-    /**
-     * Returns the value associated with the given key, or defaultValue if
-     * no mapping of the desired type exists for the given key.
-     *
-     * @param key a String
-     * @param defaultValue Value to return if key does not exist
-     * @return a boolean value
-     */
-    @Override
-    public boolean getBoolean(String key, boolean defaultValue) {
-        return super.getBoolean(key, defaultValue);
-    }
-
-    /**
      * Returns the value associated with the given key, or (byte) 0 if
      * no mapping of the desired type exists for the given key.
      *
@@ -939,19 +890,6 @@
      * value is explicitly associated with the key.
      *
      * @param key a String, or null
-     * @return a boolean[] value, or null
-     */
-    @Override
-    public boolean[] getBooleanArray(String key) {
-        return super.getBooleanArray(key);
-    }
-
-    /**
-     * Returns the value associated with the given key, or null if
-     * no mapping of the desired type exists for the given key or a null
-     * value is explicitly associated with the key.
-     *
-     * @param key a String, or null
      * @return a byte[] value, or null
      */
     @Override
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a9deaf3..b8178b4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -296,7 +296,7 @@
                 case 1: return "Stack";
                 case 2: return "Cursor";
                 case 3: return "Ashmem";
-                case 4: return "Gfx driver";
+                case 4: return "Gfx dev";
                 case 5: return "Other dev";
                 case 6: return ".so mmap";
                 case 7: return ".jar mmap";
@@ -306,9 +306,9 @@
                 case 11: return ".oat mmap";
                 case 12: return ".art mmap";
                 case 13: return "Other mmap";
-                case 14: return "Graphics";
-                case 15: return "GL";
-                case 16: return "Memtrack";
+                case 14: return "EGL mtrack";
+                case 15: return "GL mtrack";
+                case 16: return "Other mtrack";
                 case 17: return ".Heap";
                 case 18: return ".LOS";
                 case 19: return ".LinearAlloc";
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index c01f688..3a44428 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -96,7 +96,8 @@
                     !(value instanceof Double) && !(value instanceof String) &&
                     !(value instanceof int[]) && !(value instanceof long[]) &&
                     !(value instanceof double[]) && !(value instanceof String[]) &&
-                    !(value instanceof PersistableBundle) && (value != null)) {
+                    !(value instanceof PersistableBundle) && (value != null) &&
+                    !(value instanceof Boolean) && !(value instanceof boolean[])) {
                 throw new IllegalArgumentException("Bad value in PersistableBundle key=" + key +
                         " value=" + value);
             }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0062eb2..555f64c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6128,7 +6128,7 @@
 
         /**
          * The number of milliseconds to delay before sending out
-         * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcasts.
+         * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcasts. Ignored.
          *
          * @hide
          */
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 67f632f..9496b53 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -691,8 +691,8 @@
                     if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
                             + ", frame=" + mWinFrame);
                     
-                    int w = mWinFrame.width() + mOverscanInsets.left + mOverscanInsets.right;
-                    int h = mWinFrame.height() + mOverscanInsets.top + mOverscanInsets.bottom;
+                    int w = mWinFrame.width();
+                    int h = mWinFrame.height();
 
                     if (!fixedSize) {
                         final Rect padding = mIWallpaperEngine.mDisplayPadding;
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 7feca30..7b35a3b 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -148,6 +148,10 @@
         if (mState != STATE_PREPARE) {
             throw new IllegalStateException("Animator has already started, cannot change it now!");
         }
+        if (mNativePtr == null) {
+            throw new IllegalStateException("Animator's target has been destroyed "
+                    + "(trying to modify an animation after activity destroy?)");
+        }
     }
 
     static boolean isNativeInterpolator(TimeInterpolator interpolator) {
@@ -180,7 +184,10 @@
         mState = STATE_DELAYED;
         applyInterpolator();
 
-        if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
+        if (mNativePtr == null) {
+            // It's dead, immediately cancel
+            cancel();
+        } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
             nSetStartDelay(mNativePtr.get(), mStartDelay);
             doStart();
         } else {
@@ -208,7 +215,9 @@
 
     private void moveToRunningState() {
         mState = STATE_RUNNING;
-        nStart(mNativePtr.get(), this);
+        if (mNativePtr != null) {
+            nStart(mNativePtr.get());
+        }
         notifyStartListeners();
     }
 
@@ -227,7 +236,6 @@
                 getHelper().removeDelayedAnimation(this);
                 moveToRunningState();
             }
-            nEnd(mNativePtr.get());
 
             final ArrayList<AnimatorListener> listeners = cloneListeners();
             final int numListeners = listeners == null ? 0 : listeners.size();
@@ -235,10 +243,7 @@
                 listeners.get(i).onAnimationCancel(this);
             }
 
-            if (mViewTarget != null) {
-                // Kick off a frame to flush the state change
-                mViewTarget.invalidateViewProperty(true, false);
-            }
+            end();
         }
     }
 
@@ -249,10 +254,15 @@
                 getHelper().removeDelayedAnimation(this);
                 doStart();
             }
-            nEnd(mNativePtr.get());
-            if (mViewTarget != null) {
-                // Kick off a frame to flush the state change
-                mViewTarget.invalidateViewProperty(true, false);
+            if (mNativePtr != null) {
+                nEnd(mNativePtr.get());
+                if (mViewTarget != null) {
+                    // Kick off a frame to flush the state change
+                    mViewTarget.invalidateViewProperty(true, false);
+                }
+            } else {
+                // It's already dead, jump to onFinish
+                onFinished();
             }
         }
     }
@@ -281,9 +291,11 @@
     }
 
     private void setTarget(RenderNode node) {
+        checkMutable();
         if (mTarget != null) {
             throw new IllegalStateException("Target already set!");
         }
+        nSetListener(mNativePtr.get(), this);
         mTarget = node;
         mTarget.addAnimator(this);
     }
@@ -346,6 +358,12 @@
     }
 
     protected void onFinished() {
+        if (mState == STATE_PREPARE) {
+            // Unlikely but possible, the native side has been destroyed
+            // before we have started.
+            releaseNativePtr();
+            return;
+        }
         if (mState == STATE_DELAYED) {
             getHelper().removeDelayedAnimation(this);
             notifyStartListeners();
@@ -361,8 +379,14 @@
         // Release the native object, as it has a global reference to us. This
         // breaks the cyclic reference chain, and allows this object to be
         // GC'd
-        mNativePtr.release();
-        mNativePtr = null;
+        releaseNativePtr();
+    }
+
+    private void releaseNativePtr() {
+        if (mNativePtr != null) {
+            mNativePtr.release();
+            mNativePtr = null;
+        }
     }
 
     @SuppressWarnings("unchecked")
@@ -484,7 +508,8 @@
     private static native void nSetStartDelay(long nativePtr, long startDelay);
     private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
     private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
+    private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
 
-    private static native void nStart(long animPtr, RenderNodeAnimator finishListener);
+    private static native void nStart(long animPtr);
     private static native void nEnd(long animPtr);
 }
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 14b950f..ad4a048 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -37,6 +37,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashSet;
 
 /**
@@ -465,11 +466,13 @@
             final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
 
             final int count = drawables.size();
+            ArrayList<Bitmap> tmpList = new ArrayList<Bitmap>();
             for (int i = 0; i < count; i++) {
-                final Bitmap bitmap = drawables.valueAt(i).getBitmap();
-                if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
-                    preloadedPointers.add(bitmap.mNativeBitmap);
+                drawables.valueAt(i).addAtlasableBitmaps(tmpList);
+                for (int j = 0; j < tmpList.size(); j++) {
+                    preloadedPointers.add(tmpList.get(j).mNativeBitmap);
                 }
+                tmpList.clear();
             }
 
             for (int i = 0; i < map.length; i += 4) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2bb1ebc..75411fe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8185,8 +8185,10 @@
     * @see #performAccessibilityAction(int, Bundle)
     *
     * Note: Called from the default {@link AccessibilityDelegate}.
+    *
+    * @hide Until we've refactored all accessibility delegation methods.
     */
-    boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
         switch (action) {
             case AccessibilityNodeInfo.ACTION_CLICK: {
                 if (isClickable()) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 25a70eb..22c5185 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -825,6 +825,12 @@
             return false;
         }
 
+        // Clip the bounds by our bounds.
+        bounds.left = Math.max(bounds.left, 0);
+        bounds.top = Math.max(bounds.top, 0);
+        bounds.right = Math.min(bounds.right, mRight);
+        bounds.bottom = Math.min(bounds.bottom, mBottom);
+
         Iterator<View> iterator = obtainOrderedChildIterator();
         while (iterator.hasNext()) {
             View sibling = iterator.next();
@@ -5113,7 +5119,8 @@
         final int height = mBottom - mTop;
 
         boolean rectIsVisible = true;
-        if (mParent instanceof ViewGroup && ((ViewGroup)mParent).getClipChildren()) {
+        if (mParent == null ||
+                (mParent instanceof ViewGroup && ((ViewGroup) mParent).getClipChildren())) {
             // Clip to bounds.
             rectIsVisible = rect.intersect(0, 0, width, height);
         }
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 820bf78..e75643ab 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -329,7 +329,6 @@
             String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
             mAnimator.announceForAccessibility(fullDateText);
         }
-        updatePickers();
     }
 
     private void setCurrentView(final int viewIndex) {
@@ -369,11 +368,13 @@
     @Override
     public void init(int year, int monthOfYear, int dayOfMonth,
             DatePicker.OnDateChangedListener callBack) {
-        mDateChangedListener = callBack;
         mCurrentDate.set(Calendar.YEAR, year);
         mCurrentDate.set(Calendar.MONTH, monthOfYear);
         mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
-        updateDisplay(false);
+
+        mDateChangedListener = callBack;
+
+        onDateChanged(false, false);
     }
 
     @Override
@@ -381,10 +382,29 @@
         mCurrentDate.set(Calendar.YEAR, year);
         mCurrentDate.set(Calendar.MONTH, month);
         mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
-        if (mDateChangedListener != null) {
-            mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
+
+        onDateChanged(false, true);
+    }
+
+    private void onDateChanged(boolean fromUser, boolean callbackToClient) {
+        if (callbackToClient && mDateChangedListener != null) {
+            final int year = mCurrentDate.get(Calendar.YEAR);
+            final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
+            final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
+            mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
         }
-        updateDisplay(false);
+
+        for (OnDateChangedListener listener : mListeners) {
+            listener.onDateChanged();
+        }
+
+        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
+
+        updateDisplay(fromUser);
+
+        if (fromUser) {
+            tryVibrate();
+        }
     }
 
     @Override
@@ -411,8 +431,7 @@
         }
         if (mCurrentDate.before(mTempDate)) {
             mCurrentDate.setTimeInMillis(minDate);
-            updatePickers();
-            updateDisplay(false);
+            onDateChanged(false, true);
         }
         mMinDate.setTimeInMillis(minDate);
         mDayPickerView.setMinDate(minDate);
@@ -433,8 +452,7 @@
         }
         if (mCurrentDate.after(mTempDate)) {
             mCurrentDate.setTimeInMillis(maxDate);
-            updatePickers();
-            updateDisplay(false);
+            onDateChanged(false, true);
         }
         mMaxDate.setTimeInMillis(maxDate);
         mDayPickerView.setMaxDate(maxDate);
@@ -573,9 +591,10 @@
     public void onYearSelected(int year) {
         adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
         mCurrentDate.set(Calendar.YEAR, year);
-        updatePickers();
+        onDateChanged(true, true);
+
+        // Auto-advance to month and day view.
         setCurrentView(MONTH_AND_DAY_VIEW);
-        updateDisplay(true);
     }
 
     // If the newly selected month / year does not contain the currently selected day number,
@@ -612,14 +631,6 @@
         }
     }
 
-    private void updatePickers() {
-        for (OnDateChangedListener listener : mListeners) {
-            listener.onDateChanged();
-        }
-
-        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
-    }
-
     @Override
     public void registerOnDateChangedListener(OnDateChangedListener listener) {
         mListeners.add(listener);
@@ -653,11 +664,7 @@
         @Override
         public void onDaySelected(DayPickerView view, Calendar day) {
             mCurrentDate.setTimeInMillis(day.getTimeInMillis());
-
-            updatePickers();
-            updateDisplay(true);
-
-            tryVibrate();
+            onDateChanged(true, true);
         }
     };
 
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 75c6184..7b64cf5 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -1456,6 +1456,32 @@
 
             final boolean selected = isVirtualViewSelected(type, value);
             node.setSelected(selected);
+
+            final int nextId = getVirtualViewIdAfter(type, value);
+            if (nextId != INVALID_ID) {
+                node.setTraversalBefore(RadialTimePickerView.this, nextId);
+            }
+        }
+
+        private int getVirtualViewIdAfter(int type, int value) {
+            if (type == TYPE_HOUR) {
+                final int nextValue = value + 1;
+                final int max = mIs24HourMode ? 23 : 12;
+                if (nextValue <= max) {
+                    return makeId(type, nextValue);
+                }
+            } else if (type == TYPE_MINUTE) {
+                final int current = getCurrentMinute();
+                final int snapValue = value - (value % MINUTE_INCREMENT);
+                final int nextValue = snapValue + MINUTE_INCREMENT;
+                if (value < current && nextValue > current) {
+                    // The current value is between two snap values.
+                    return makeId(type, current);
+                } else if (nextValue < 60) {
+                    return makeId(type, nextValue);
+                }
+            }
+            return INVALID_ID;
         }
 
         @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 34b3a72..765d196 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8475,8 +8475,14 @@
         }
     }
 
+    /**
+     * Performs an accessibility action after it has been offered to the
+     * delegate.
+     *
+     * @hide
+     */
     @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
         switch (action) {
             case AccessibilityNodeInfo.ACTION_CLICK: {
                 boolean handled = false;
@@ -8557,10 +8563,10 @@
             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
                 ensureIterableTextForAccessibilitySelectable();
-                return super.performAccessibilityAction(action, arguments);
+                return super.performAccessibilityActionInternal(action, arguments);
             }
             default: {
-                return super.performAccessibilityAction(action, arguments);
+                return super.performAccessibilityActionInternal(action, arguments);
             }
         }
     }
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index d61b6fc..8d475a7 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -33,9 +33,11 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import com.android.internal.R;
 
@@ -136,9 +138,13 @@
         // Set up hour/minute labels.
         mHourView = (TextView) mHeaderView.findViewById(R.id.hours);
         mHourView.setOnClickListener(mClickListener);
+        mHourView.setAccessibilityDelegate(
+                new ClickActionDelegate(context, R.string.select_hours));
         mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator);
         mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes);
         mMinuteView.setOnClickListener(mClickListener);
+        mMinuteView.setAccessibilityDelegate(
+                new ClickActionDelegate(context, R.string.select_minutes));
 
         final int headerTimeTextAppearance = a.getResourceId(
                 R.styleable.TimePicker_headerTimeTextAppearance, 0);
@@ -206,6 +212,22 @@
         initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX);
     }
 
+    private static class ClickActionDelegate extends AccessibilityDelegate {
+        private final AccessibilityAction mClickAction;
+
+        public ClickActionDelegate(Context context, int resId) {
+            mClickAction = new AccessibilityAction(
+                    AccessibilityNodeInfo.ACTION_CLICK, context.getString(resId));
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+
+            info.addAction(mClickAction);
+        }
+    }
+
     private int computeStableWidth(TextView v, int maxNumber) {
         int maxWidth = 0;
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 634d03d..661acbe 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -248,12 +248,14 @@
         }
         mAlwaysUseOption = alwaysUseOption;
 
-        int count = mAdapter.mList.size();
         if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
             // Gulp!
             finish();
             return;
-        } else if (count > 1) {
+        }
+
+        int count = mAdapter.mList.size();
+        if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
             setContentView(layoutId);
             mListView = (ListView) findViewById(R.id.resolver_list);
             mListView.setAdapter(mAdapter);
@@ -797,11 +799,9 @@
         }
 
         public void handlePackagesChanged() {
-            final int oldItemCount = getCount();
             rebuildList();
             notifyDataSetChanged();
-            final int newItemCount = getCount();
-            if (newItemCount == 0) {
+            if (getCount() == 0) {
                 // We no longer have any items...  just finish the activity.
                 finish();
             }
@@ -956,6 +956,13 @@
                 // Process last group
                 processGroup(currentResolveList, start, (N-1), r0, r0Label);
             }
+
+            // Layout doesn't handle both profile button and last chosen
+            // so disable last chosen if profile button is present.
+            if (mOtherProfile != null && mLastChosenPosition >= 0) {
+                mLastChosenPosition = -1;
+                mFilterLastUsed = false;
+            }
         }
 
         private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
@@ -963,14 +970,9 @@
             // Process labels from start to i
             int num = end - start+1;
             if (num == 1) {
-                if (mLastChosen != null
-                        && mLastChosen.activityInfo.packageName.equals(
-                                ro.activityInfo.packageName)
-                        && mLastChosen.activityInfo.name.equals(ro.activityInfo.name)) {
-                    mLastChosenPosition = mList.size();
-                }
                 // No duplicate labels. Use label for entry at start
                 addResolveInfo(new DisplayResolveInfo(ro, roLabel, null, null));
+                updateLastChosenPosition(ro);
             } else {
                 mShowExtended = true;
                 boolean usePkg = false;
@@ -998,12 +1000,6 @@
                 }
                 for (int k = start; k <= end; k++) {
                     ResolveInfo add = rList.get(k);
-                    if (mLastChosen != null
-                            && mLastChosen.activityInfo.packageName.equals(
-                                    add.activityInfo.packageName)
-                            && mLastChosen.activityInfo.name.equals(add.activityInfo.name)) {
-                        mLastChosenPosition = mList.size();
-                    }
                     if (usePkg) {
                         // Use application name for all entries from start to end-1
                         addResolveInfo(new DisplayResolveInfo(add, roLabel,
@@ -1013,10 +1009,19 @@
                         addResolveInfo(new DisplayResolveInfo(add, roLabel,
                                 add.activityInfo.applicationInfo.loadLabel(mPm), null));
                     }
+                    updateLastChosenPosition(add);
                 }
             }
         }
 
+        private void updateLastChosenPosition(ResolveInfo info) {
+            if (mLastChosen != null
+                    && mLastChosen.activityInfo.packageName.equals(info.activityInfo.packageName)
+                    && mLastChosen.activityInfo.name.equals(info.activityInfo.name)) {
+                mLastChosenPosition = mList.size() - 1;
+            }
+        }
+
         private void addResolveInfo(DisplayResolveInfo dri) {
             if (dri.ri.targetUserId != UserHandle.USER_CURRENT && mOtherProfile == null) {
                 // So far we only support a single other profile at a time.
@@ -1217,4 +1222,3 @@
         }
     }
 }
-
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index e9baaa8..2bd607c 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -520,7 +520,7 @@
      * Flatten a String[] into an XmlSerializer.  The list can later be read back
      * with readThisStringArrayXml().
      *
-     * @param val The long array to be flattened.
+     * @param val The String array to be flattened.
      * @param name Name attribute to include with this array's tag, or null for
      *             none.
      * @param out XmlSerializer to write the array into.
@@ -556,6 +556,45 @@
     }
 
     /**
+     * Flatten a boolean[] into an XmlSerializer.  The list can later be read back
+     * with readThisBooleanArrayXml().
+     *
+     * @param val The boolean array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeBooleanArrayXml(boolean[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, java.io.IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "boolean-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Boolean.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "boolean-array");
+    }
+
+    /**
      * Flatten an object's value into an XmlSerializer.  The value can later
      * be read back with readThisValueXml().
      *
@@ -636,6 +675,9 @@
         } else if (v instanceof String[]) {
             writeStringArrayXml((String[])v, name, out);
             return;
+        } else if (v instanceof boolean[]) {
+            writeBooleanArrayXml((boolean[])v, name, out);
+            return;
         } else if (v instanceof Map) {
             writeMapXml((Map)v, name, out);
             return;
@@ -1169,6 +1211,66 @@
     }
 
     /**
+     * Read a boolean[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeBooleanArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated boolean[].
+     *
+     * @see #readListXml
+     */
+    public static final boolean[] readThisBooleanArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, java.io.IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        boolean[] array = new boolean[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Boolean.valueOf(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
      * Read a flattened object from an XmlPullParser.  The XML data could
      * previously have been written with writeMapXml(), writeListXml(), or
      * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
@@ -1259,6 +1361,11 @@
             name[0] = valueName;
             //System.out.println("Returning value for " + valueName + ": " + res);
             return res;
+        } else if (tagName.equals("boolean-array")) {
+            res = readThisBooleanArrayXml(parser, "boolean-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
         } else if (tagName.equals("map")) {
             parser.next();
             res = readThisMapXml(parser, "map", name);
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 25b4945..ed7af2f 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -217,8 +217,9 @@
                 mInitialTouchX = x;
                 mInitialTouchY = mLastTouchY = y;
                 mActivePointerId = ev.getPointerId(0);
-                mIsDragging = findChildUnder(mInitialTouchX, mInitialTouchY) != null;
-                handled = (!mIsDragging && mOnDismissedListener != null) || mCollapsibleHeight > 0;
+                final boolean hitView = findChildUnder(mInitialTouchX, mInitialTouchY) != null;
+                handled = (!hitView && mOnDismissedListener != null) || mCollapsibleHeight > 0;
+                mIsDragging = hitView && handled;
                 abortAnimation();
             }
             break;
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index d39bf07..155f5d3 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -142,6 +142,8 @@
                     "SYSTEM_LAST_KMSG");
             addFileToDropBox(db, prefs, headers, "/cache/recovery/log",
                     -LOG_SIZE, "SYSTEM_RECOVERY_LOG");
+            addFileToDropBox(db, prefs, headers, "/cache/recovery/last_kmsg",
+                    -LOG_SIZE, "SYSTEM_RECOVERY_KMSG");
             addFileToDropBox(db, prefs, headers, "/data/dontpanic/apanic_console",
                     -LOG_SIZE, "APANIC_CONSOLE");
             addFileToDropBox(db, prefs, headers, "/data/dontpanic/apanic_threads",
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 8440a0e..b27add8 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -49,36 +49,35 @@
 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
 
 /**
- * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for
- * digital RGB with K_b = 0.114, and K_r = 0.299.
+ * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02
  */
 static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane,
         uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
     uint8_t R, G, B;
     size_t index = 0;
-
-    size_t cStrideDiff = chromaStride - width;
-
     for (size_t j = 0; j < height; j++) {
+        uint8_t* u = uPlane;
+        uint8_t* v = vPlane;
+        uint8_t* y = yPlane;
+        bool jEven = (j & 1) == 0;
         for (size_t i = 0; i < width; i++) {
             R = rgbBuf[index++];
             G = rgbBuf[index++];
             B = rgbBuf[index++];
-            *(yPlane + i) = ((66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
-
-            if (j % 2 == 0 && i % 2 == 0){
-                *uPlane = (( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;
-                *vPlane = (( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;
-                uPlane += chromaStep;
-                vPlane += chromaStep;
+            *y++ = (77 * R + 150 * G +  29 * B) >> 8;
+            if (jEven && (i & 1) == 0) {
+                *v = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
+                *u = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
+                u += chromaStep;
+                v += chromaStep;
             }
             // Skip alpha
             index++;
         }
         yPlane += yStride;
-        if (j % 2 == 0) {
-            uPlane += cStrideDiff;
-            vPlane += cStrideDiff;
+        if (jEven) {
+            uPlane += chromaStride;
+            vPlane += chromaStride;
         }
     }
 }
@@ -87,8 +86,10 @@
     size_t cStep = ycbcr->chroma_step;
     size_t cStride = ycbcr->cstride;
     size_t yStride = ycbcr->ystride;
+    ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride,
+            cStep);
     rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y),
-            reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr),
+            reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb),
             cStep, yStride, cStride);
 }
 
@@ -231,6 +232,7 @@
 
     size_t totalSizeBytes = tmpSize;
 
+    ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt);
     switch(pixelFmt) {
         case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
             if (bufferLength < totalSizeBytes) {
@@ -276,6 +278,7 @@
             }
 
             uint32_t stride = buf->getStride();
+            ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride);
             LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride);
 
             uint32_t cStride = ALIGN(stride / 2, 16);
@@ -470,6 +473,26 @@
     return NO_ERROR;
 }
 
+static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz,
+          jobject surface) {
+    ALOGV("nativeDetectSurfaceUsageFlags");
+
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        jniThrowException(env, "Ljava/lang/UnsupportedOperationException;",
+            "Could not retrieve native window from surface.");
+        return BAD_VALUE;
+    }
+    int32_t usage = 0;
+    status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage);
+    if(err != NO_ERROR) {
+        jniThrowException(env, "Ljava/lang/UnsupportedOperationException;",
+            "Error while querying surface usage bits");
+        return err;
+    }
+    return usage;
+}
+
 static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz,
         jobject surfaceTexture, jintArray dimens) {
     ALOGV("nativeDetectTextureDimens");
@@ -713,6 +736,9 @@
     { "nativeGetJpegFooterSize",
     "()I",
     (void *)LegacyCameraDevice_nativeGetJpegFooterSize },
+    { "nativeDetectSurfaceUsageFlags",
+    "(Landroid/view/Surface;)I",
+    (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags },
 };
 
 // Get all the required offsets in java class and register native functions
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index cabe200..fee1ead 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -25,6 +25,7 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include <media/AudioSystem.h>
+#include <media/AudioPolicy.h>
 
 #include <system/audio.h>
 #include <system/audio_policy.h>
@@ -40,6 +41,7 @@
 static jclass gArrayListClass;
 static struct {
     jmethodID    add;
+    jmethodID    toArray;
 } gArrayListMethods;
 
 static jclass gAudioHandleClass;
@@ -102,6 +104,42 @@
     // other fields unused by JNI
 } gAudioPatchFields;
 
+static jclass gAudioMixClass;
+static struct {
+    jfieldID    mRule;
+    jfieldID    mFormat;
+    jfieldID    mRouteFlags;
+    jfieldID    mRegistrationId;
+    jfieldID    mMixType;
+} gAudioMixFields;
+
+static jclass gAudioFormatClass;
+static struct {
+    jfieldID    mEncoding;
+    jfieldID    mSampleRate;
+    jfieldID    mChannelMask;
+    // other fields unused by JNI
+} gAudioFormatFields;
+
+static jclass gAudioMixingRuleClass;
+static struct {
+    jfieldID    mCriteria;
+    // other fields unused by JNI
+} gAudioMixingRuleFields;
+
+static jclass gAttributeMatchCriterionClass;
+static struct {
+    jfieldID    mAttr;
+    jfieldID    mRule;
+} gAttributeMatchCriterionFields;
+
+static jclass gAudioAttributesClass;
+static struct {
+    jfieldID    mUsage;
+    jfieldID    mSource;
+} gAudioAttributesFields;
+
+
 static const char* const kEventHandlerClassPathName =
         "android/media/AudioPortEventHandler";
 static jmethodID gPostEventFromNative;
@@ -1322,6 +1360,128 @@
     return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId);
 }
 
+
+
+
+static jint convertAudioMixToNative(JNIEnv *env,
+                                    AudioMix *nAudioMix,
+                                    const jobject jAudioMix)
+{
+    nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
+    nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
+
+    jstring jRegistrationId = (jstring)env->GetObjectField(jAudioMix,
+                                                           gAudioMixFields.mRegistrationId);
+    const char *nRegistrationId = env->GetStringUTFChars(jRegistrationId, NULL);
+    nAudioMix->mRegistrationId = String8(nRegistrationId);
+    env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId);
+    env->DeleteLocalRef(jRegistrationId);
+
+    jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
+    nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
+                                                     gAudioFormatFields.mSampleRate);
+    nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
+                                                     gAudioFormatFields.mChannelMask));
+    nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
+                                                     gAudioFormatFields.mEncoding));
+    env->DeleteLocalRef(jFormat);
+
+    jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
+    jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
+    env->DeleteLocalRef(jRule);
+    jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
+                                                                 gArrayListMethods.toArray);
+    env->DeleteLocalRef(jRuleCriteria);
+
+    jint numCriteria = env->GetArrayLength(jCriteria);
+    if (numCriteria > MAX_CRITERIA_PER_MIX) {
+        numCriteria = MAX_CRITERIA_PER_MIX;
+    }
+
+    for (jint i = 0; i < numCriteria; i++) {
+        AttributeMatchCriterion nCriterion;
+
+        jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
+
+        nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule);
+
+        jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr);
+        if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
+                nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
+            nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes,
+                                                       gAudioAttributesFields.mUsage);
+        } else {
+            nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes,
+                                                        gAudioAttributesFields.mSource);
+        }
+        env->DeleteLocalRef(jAttributes);
+
+        nAudioMix->mCriteria.add(nCriterion);
+        env->DeleteLocalRef(jCriterion);
+    }
+
+    env->DeleteLocalRef(jCriteria);
+
+    return (jint)AUDIO_JAVA_SUCCESS;
+}
+
+static jint
+android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
+                                              jobject jMixesList, jboolean registration)
+{
+    ALOGV("registerPolicyMixes");
+
+    if (jMixesList == NULL) {
+        return (jint)AUDIO_JAVA_BAD_VALUE;
+    }
+    if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
+        return (jint)AUDIO_JAVA_BAD_VALUE;
+    }
+    jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
+                                                              gArrayListMethods.toArray);
+    jint numMixes = env->GetArrayLength(jMixes);
+    if (numMixes > MAX_MIXES_PER_POLICY) {
+        numMixes = MAX_MIXES_PER_POLICY;
+    }
+
+    status_t status;
+    jint jStatus;
+    jobject jAudioMix = NULL;
+    Vector <AudioMix> mixes;
+    for (jint i = 0; i < numMixes; i++) {
+        jAudioMix = env->GetObjectArrayElement(jMixes, i);
+        if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
+            jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
+            goto exit;
+        }
+        AudioMix mix;
+        jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
+        env->DeleteLocalRef(jAudioMix);
+        jAudioMix = NULL;
+        if (jStatus != AUDIO_JAVA_SUCCESS) {
+            goto exit;
+        }
+        mixes.add(mix);
+    }
+
+    ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
+    status = AudioSystem::registerPolicyMixes(mixes, registration);
+    ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
+
+    jStatus = nativeToJavaStatus(status);
+    if (jStatus != AUDIO_JAVA_SUCCESS) {
+        goto exit;
+    }
+
+exit:
+    if (jAudioMix != NULL) {
+        env->DeleteLocalRef(jAudioMix);
+    }
+    return jStatus;
+}
+
+
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -1363,6 +1523,9 @@
                                             (void *)android_media_AudioSystem_setAudioPortConfig},
     {"getAudioHwSyncForSession", "(I)I",
                                     (void *)android_media_AudioSystem_getAudioHwSyncForSession},
+    {"registerPolicyMixes",    "(Ljava/util/ArrayList;Z)I",
+                                            (void *)android_media_AudioSystem_registerPolicyMixes},
+
 };
 
 
@@ -1381,6 +1544,7 @@
     jclass arrayListClass = env->FindClass("java/util/ArrayList");
     gArrayListClass = (jclass) env->NewGlobalRef(arrayListClass);
     gArrayListMethods.add = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
+    gArrayListMethods.toArray = env->GetMethodID(arrayListClass, "toArray", "()[Ljava/lang/Object;");
 
     jclass audioHandleClass = env->FindClass("android/media/AudioHandle");
     gAudioHandleClass = (jclass) env->NewGlobalRef(audioHandleClass);
@@ -1462,6 +1626,41 @@
                                             "(Ljava/lang/Object;IIILjava/lang/Object;)V");
 
 
+    jclass audioMixClass = env->FindClass("android/media/audiopolicy/AudioMix");
+    gAudioMixClass = (jclass) env->NewGlobalRef(audioMixClass);
+    gAudioMixFields.mRule = env->GetFieldID(audioMixClass, "mRule",
+                                                "Landroid/media/audiopolicy/AudioMixingRule;");
+    gAudioMixFields.mFormat = env->GetFieldID(audioMixClass, "mFormat",
+                                                "Landroid/media/AudioFormat;");
+    gAudioMixFields.mRouteFlags = env->GetFieldID(audioMixClass, "mRouteFlags", "I");
+    gAudioMixFields.mRegistrationId = env->GetFieldID(audioMixClass, "mRegistrationId",
+                                                      "Ljava/lang/String;");
+    gAudioMixFields.mMixType = env->GetFieldID(audioMixClass, "mMixType", "I");
+
+    jclass audioFormatClass = env->FindClass("android/media/AudioFormat");
+    gAudioFormatClass = (jclass) env->NewGlobalRef(audioFormatClass);
+    gAudioFormatFields.mEncoding = env->GetFieldID(audioFormatClass, "mEncoding", "I");
+    gAudioFormatFields.mSampleRate = env->GetFieldID(audioFormatClass, "mSampleRate", "I");
+    gAudioFormatFields.mChannelMask = env->GetFieldID(audioFormatClass, "mChannelMask", "I");
+
+    jclass audioMixingRuleClass = env->FindClass("android/media/audiopolicy/AudioMixingRule");
+    gAudioMixingRuleClass = (jclass) env->NewGlobalRef(audioMixingRuleClass);
+    gAudioMixingRuleFields.mCriteria = env->GetFieldID(audioMixingRuleClass, "mCriteria",
+                                                       "Ljava/util/ArrayList;");
+
+    jclass attributeMatchCriterionClass =
+                env->FindClass("android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion");
+    gAttributeMatchCriterionClass = (jclass) env->NewGlobalRef(attributeMatchCriterionClass);
+    gAttributeMatchCriterionFields.mAttr = env->GetFieldID(attributeMatchCriterionClass, "mAttr",
+                                                       "Landroid/media/AudioAttributes;");
+    gAttributeMatchCriterionFields.mRule = env->GetFieldID(attributeMatchCriterionClass, "mRule",
+                                                       "I");
+
+    jclass audioAttributesClass = env->FindClass("android/media/AudioAttributes");
+    gAudioAttributesClass = (jclass) env->NewGlobalRef(audioAttributesClass);
+    gAudioAttributesFields.mUsage = env->GetFieldID(audioAttributesClass, "mUsage", "I");
+    gAudioAttributesFields.mSource = env->GetFieldID(audioAttributesClass, "mSource", "I");
+
     AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
 
     int status = AndroidRuntime::registerNativeMethods(env,
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 5a32718..d9e64c7 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -528,8 +528,8 @@
                         c++;
                     }
                     pss += atoi(c);
-                } else if (strncmp(line, "Private_Clean:", 14)
-                        || strncmp(line, "Private_Dirty:", 14)) {
+                } else if (strncmp(line, "Private_Clean:", 14) == 0
+                        || strncmp(line, "Private_Dirty:", 14) == 0) {
                     char* c = line + 14;
                     while (*c != 0 && (*c < '0' || *c > '9')) {
                         c++;
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index 311882d..eb56639 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -177,9 +177,13 @@
     animator->setAllowRunningAsync(mayRunAsync);
 }
 
-static void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) {
+static void setListener(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) {
     BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
     animator->setListener(new AnimationListenerBridge(env, finishListener));
+}
+
+static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) {
+    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
     animator->start();
 }
 
@@ -208,7 +212,8 @@
     { "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
     { "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
     { "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync },
-    { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start },
+    { "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener},
+    { "nStart", "(J)V", (void*) start},
     { "nEnd", "(J)V", (void*) end },
 #endif
 };
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 84cbf78..1670857 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -47,7 +47,7 @@
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Telefonsvarer"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Forbindelsesproblemer eller ugyldigt MMI-nummer."</string>
-    <string name="mmiFdnError" msgid="5224398216385316471">"Du kan kun foretage handlinger med faste opkaldsnumre."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Du kan kun foretage handlinger med dine numre til begrænset opkald."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"Tjenesten blev aktiveret."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Tjenesten blev aktiveret for:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"Tjenesten er deaktiveret."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 031b4d9..fd2b6cc 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1287,7 +1287,7 @@
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapport"</string>
     <string name="wait" msgid="7147118217226317732">"Attendre"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas.\n \nVoulez-vous la fermer ?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas.\n \nVoulez-vous quitter ?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Application redirigée"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Application lancée initialement : <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 91ac0a7..c6015c2 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -69,7 +69,7 @@
   </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"លេខ​សម្គាល់​អ្នក​ហៅ​​ចូល​"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"លេខ​សម្គាល់​អ្នក​ហៅ​​ចូល"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"លេខ​សម្គាល់​អ្នក​ហៅ​ចេញ"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"បាន​ភ្ជាប់​លេខ​សម្គាល់​បន្ទាត់"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"បាន​ភ្ជាប់​ការ​ដាក់កម្រិត​លេខ​សម្គាល់​បន្ទាត់"</string>
@@ -132,7 +132,7 @@
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិន​បាន​បញ្ជូន​បន្ត"</string>
     <string name="fcComplete" msgid="3118848230966886575">"កូដ​លក្ខណៈ​ពេញលេញ។"</string>
     <string name="fcError" msgid="3327560126588500777">"បញ្ហា​ការ​តភ្ជាប់​ ឬ​កូដ​លក្ខណៈ​​​មិន​ត្រឹមត្រូវ​។"</string>
-    <string name="httpErrorOk" msgid="1191919378083472204">"យល់​ព្រម​"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"យល់​ព្រម"</string>
     <string name="httpError" msgid="7956392511146698522">"មាន​កំហុស​បណ្ដាញ។"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"រក​មិន​ឃើញ URL ។"</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"គ្រោងការណ៍​ផ្ទៀងផ្ទាត់​តំបន់បណ្ដាញ​មិន​ត្រូវ​បាន​គាំទ្រ។"</string>
@@ -199,7 +199,7 @@
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើក​សំឡេង"</string>
     <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"ពេល​ជិះ​យន្តហោះ"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"បាន​បើក​របៀប​ពេល​ជិះ​យន្ត​ហោះ"</string>
-    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បាន​បិទ​របៀបពេលជិះ​យន្តហោះ​"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បាន​បិទ​របៀបពេលជិះ​យន្តហោះ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"ការ​កំណត់"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោ​ឥឡូវនេះ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -212,7 +212,7 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"សារ​របស់​អ្នក"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និង​សរសេរ​សារ SMS, អ៊ីមែល និង​សារ​ផ្សេងៗ​ទៀត​របស់​អ្នក។"</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មាន​ផ្ទាល់ខ្លួន​របស់​អ្នក"</string>
-    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​អ្នក​ ដែល​បា​ន​រក្សាទុក​ក្នុង​កាត​ទំនាក់ទំនង​របស់​អ្នក។​"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​អ្នក​ ដែល​បា​ន​រក្សាទុក​ក្នុង​កាត​ទំនាក់ទំនង​របស់​អ្នក។"</string>
     <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មាន​សង្គម​របស់​អ្នក"</string>
     <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​ទំនាក់ទំនង និង​ការ​ភ្ជាប់​សង្គម​របស់​អ្នក។"</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំង​របស់​អ្នក"</string>
@@ -408,7 +408,7 @@
     <string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យ​កម្មវិធី​មើល​គ្រាប់​ចុច​ដែល​អ្នក​ចុច​ពេល​មាន​អន្តរកម្ម​ជា​មួយ​កម្មវិធី​ផ្សេង (ដូចជា បញ្ចូល​ពាក្យ​សម្ងាត់)។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចង​ទៅ​វិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​វិធី​សាស្ត្រ​បញ្ចូល។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
-    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចង​សេវា​កម្ម​ភាព​មធ្យោបាយ​ងាយស្រួល​"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចង​សេវា​កម្ម​ភាព​មធ្យោបាយ​ងាយស្រួល"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យ​​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ភាព​ងាយស្រួល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"ចង​សេវាកម្ម​​បោះពុម្ព"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
@@ -428,7 +428,7 @@
     <string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​គ្រប់គ្រង​ឃ្លា​​សម្រាប់​​ការ​រក​ឃើញ​​​ពាក្យ​​ជា​សំឡេង។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់​ទៅ​ការ​បង្ហាញ​ពី​ចម្ងាយ"</string>
     <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​ការ​បង្ហាញ​ពី​ចម្ងាយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
-    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក​"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទង​ជា​មួយ​អ្នកគ្រប់គ្រង​ឧបករណ៍"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យ​ម្ចាស់​ផ្ញើ​គោលបំណង​​ទៅ​អ្នក​គ្រប់គ្រង​ឧបករណ៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
@@ -436,7 +436,7 @@
     <string name="permdesc_bindTvInput" msgid="2371008331852001924">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ចំណុចប្រទាក់​កម្រិត​ខ្ពស់​នៃ​ការ​បញ្ចូល​ទូរទស្សន៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_modifyParentalControls" msgid="4611318225997592242">"កែប្រែ​ការ​ត្រួតពិនិត្យ​មាតាបិតា"</string>
     <string name="permdesc_modifyParentalControls" msgid="7438482894162282039">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​​កែប្រែ​ទិន្នន័យ​ការ​ត្រួតពិនិត្យ​មាតាបិតា​​របស់​ប្រព័ន្ធ​។ គួរ​តែ​មិន​ត្រូវការ​សម្រាប់​កម្មវិធី​ធម្មតា​។"</string>
-    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​​​ឧបករណ៍​​"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​​​ឧបករណ៍"</string>
     <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាត​​​ឲ្យ​ម្ចាស់​​​បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​ឧបករណ៍​សកម្ម​ចេញ​។ មិន​គួរ​ប្រើ​សម្រាប់​កម្មវិធី​​ធម្មតា​ទេ​។"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរ​ទិស​អេក្រង់"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​បង្វិល​អេក្រង់​នៅ​ពេល​ណា​មួយ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
@@ -449,9 +449,9 @@
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើ​ឲ្យ​កម្មវិធី​ដំណើរការ​ជា​និច្ច"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យ​កម្មវិធី​ធ្វើជា​ផ្នែក​​ស្ថិតស្ថេរ​ដោយ​ខ្លួន​ឯង​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កំណត់​អង្គ​ចងចាំ​ដែល​អាច​ប្រើ​បាន​ចំពោះ​កម្មវិធី​ផ្សេងៗ​ ដោយ​ធ្វើឲ្យ​កុំព្យូទ័រ​បន្ទះ​យឺត។"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"អនុញ្ញាតឲ្យកម្មវិធីធ្វើឲ្យផ្នែកមួយចំនួនរបស់វាបន្តនៅក្នុងមេម៉ូរី។ វាអាចកម្រិតមេម៉ូរីដែលមានសម្រាប់កម្មវិធីផ្សេងទៀត ដែលធ្វើឲ្យទូរទស្សន៍ដើរយឺត។"</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យ​កម្មវិធី ធ្វើជា​ផ្នែក​អចិន្ត្រៃយ៍​នៃ​ខ្លួន​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កម្រិត​អង្គ​ចងចាំ​អាច​ប្រើ​បាន​ ដើម្បី​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ធ្វើ​ឲ្យ​ទូរស័ព្ទ​របស់​អ្នក​យឺត។​"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យ​កម្មវិធី ធ្វើជា​ផ្នែក​អចិន្ត្រៃយ៍​នៃ​ខ្លួន​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កម្រិត​អង្គ​ចងចាំ​អាច​ប្រើ​បាន​ ដើម្បី​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ធ្វើ​ឲ្យ​ទូរស័ព្ទ​របស់​អ្នក​យឺត។"</string>
     <string name="permlab_deletePackages" msgid="184385129537705938">"លុប​កម្មវិធី"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យ​កម្មវិធី​លុប​កញ្ចប់ Android ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប​កម្មវិធី​សំខាន់​ៗ។ ​"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យ​កម្មវិធី​លុប​កញ្ចប់ Android ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប​កម្មវិធី​សំខាន់​ៗ។"</string>
     <string name="permlab_clearAppUserData" msgid="274109191845842756">"លុប​ទិន្នន័យ​របស់​​កម្មវិធី​ផ្សេង"</string>
     <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យ​កម្មវិធី​សម្អាត​ទិន្នន័យ​អ្នក​ប្រើ។"</string>
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុប​ឃ្លាំង​សម្ងាត់​កម្មវិធី​ផ្សេងៗ"</string>
@@ -509,7 +509,7 @@
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"អនុញ្ញាតឲ្យកម្មវិធីកែសម្រួលទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានផ្ទុកនៅលើទូរទស្សន៍របស់អ្នក ដោយរាប់បញ្ចូលទាំងភាពញឹកញាប់ដែលអ្នកបានហៅ អ៊ីម៉ែល និងទំនាក់ទំនងទៅក្នុងមធ្យោបាយផ្សេងទៀតជាមួយទំនាក់ទំនងជាក់លាក់។ ការអនុញ្ញាតនេះអនុញ្ញាតឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​អំពី​ទំនាក់ទំនង​របស់​អ្នក​ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ប្រេកង់​ដែល​អ្នក​បាន​ហៅ អ៊ីមែល ឬ​បាន​ទាក់ទង​​តាម​វិធី​ផ្សេងៗ​ជា​មួយ​ទំនាក់​ទំនាក់​ជាក់លាក់។ សិទ្ធិ​នេះ​ឲ្យ​កម្មវិធី​លុប​ទិន្នន័យ​ទំនាក់ទំនង។"</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"អាន​​កំណត់​ហេតុ​​​ហៅ"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យ​កម្មវិធី​អាន​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។​"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យ​កម្មវិធី​អាន​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។"</string>
     <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"អនុញ្ញាតឲ្យកម្មវិធីអានកំណត់ហេតុហៅទរស័ព្ទទូរទស្សន៍របស់អ្នក ដោយរាប់បញ្ចូលទាំងការហៅចេញ និងហៅចូល។ ការអនុញ្ញាតនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យកំណត់ត្រាហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យកំណត់ហេតុហៅទូរស័ព្ទដោយគ្មានការដឹងលឺពីអ្នក។"</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យ​កម្មវិធី​អាន​​​បញ្ជី​ហៅ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នកដឹង។"</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរ​បញ្ជី​ហៅ"</string>
@@ -666,7 +666,7 @@
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ឲ្យ​កម្មវិធី​កំណត់​ជំនួយ​ទំហំ​ផ្ទាំង​រូបភាព​ប្រព័ន្ធ។"</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"កំណត់​ប្រព័ន្ធ​ទៅ​លំនាំដើម​រោងចក្រ​ឡើងវិញ"</string>
     <string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យ​កម្មវិធី​កំណត់​ប្រព័ន្ធ​​ដូច​ការ​កំណត់​ចេញ​ពី​រោងចក្រ​ឡើងវិញ​ពេញលេញ ដោយ​លុប​ទិន្នន័យ ការ​កំណត់​រចនាសម្ព័ន្ធ និង​កម្មវិធី​បាន​ដំឡើង។"</string>
-    <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់​​ម៉ោង​"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់​​ម៉ោង"</string>
     <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​កុំព្យូទ័រ​បន្ទះ។"</string>
     <string name="permdesc_setTime" product="tv" msgid="1826398919861882682">"អនុញ្ញាតឲ្យកម្មវិធីផ្លាស់ប្តូរម៉ោងទូរទស្សន៍។"</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​ទូរស័ព្ទ។"</string>
@@ -863,7 +863,7 @@
   <string-array name="organizationTypes">
     <item msgid="7546335612189115615">"កន្លែង​ធ្វើការ"</item>
     <item msgid="4378074129049520373">"ផ្សេងៗ"</item>
-    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ​"</item>
+    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ"</item>
   </string-array>
   <string-array name="imProtocols">
     <item msgid="8595261363518459565">"AIM"</item>
@@ -879,7 +879,7 @@
     <string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"​ចល័ត"</string>
     <string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែង​ធ្វើការ"</string>
-    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារ​កន្លែង​ធ្វើការ​"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារ​កន្លែង​ធ្វើការ"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារ​ផ្ទះ"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
     <string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
@@ -1006,7 +1006,7 @@
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ដើម្បី​ដោះ​សោ ចូល​គណនី Google របស់​អ្នក។"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ឈ្មោះ​អ្នក​ប្រើ (អ៊ីមែល​)"</string>
-    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់​"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ចូល"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។"</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ភ្លេច​ឈ្មោះ​អ្នក​ប្រើ ឬ​ពាក្យ​សម្ងាត់​របស់​អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -1051,7 +1051,7 @@
     <string name="factorytest_failed" msgid="5410270329114212041">"បាន​បរាជ័យ​ក្នុង​ការ​សាកល្បង​រោងចក្រ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវ​បាន​គាំទ្រ​សម្រាប់​តែ​កញ្ចប់​បាន​ដំឡើង​ក្នុង /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"រក​មិន​ឃើញ​កញ្ចប់​ដែល​ផ្ដល់​សកម្មភាព FACTORY_TEST ។"</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់​ផ្ដើម​ឡើង​វិញ​"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់​ផ្ដើម​ឡើង​វិញ"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"ទំព័រ​មាន​ចំណងជើង \"<xliff:g id="TITLE">%s</xliff:g>\" សរសេរ៖"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"បញ្ជាក់​ការ​រុករក"</string>
@@ -1114,7 +1114,7 @@
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"ម៉ឺនុយ +"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"ដកឃ្លា"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
-    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប​"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
     <string name="search_go" msgid="8298016669822141719">"ស្វែងរក"</string>
     <string name="search_hint" msgid="1733947260773056054">"ស្វែងរក…"</string>
     <string name="searchview_description_search" msgid="6749826639098512120">"ស្វែងរក"</string>
@@ -1199,18 +1199,18 @@
     <string name="preposition_for_date" msgid="9093949757757445117">"នៅ <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"នៅ​ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"ក្នុង​ឆ្នាំ <xliff:g id="YEAR">%s</xliff:g>"</string>
-    <string name="day" msgid="8144195776058119424">"ថ្ងៃ​"</string>
+    <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
     <string name="days" msgid="4774547661021344602">"​ថ្ងៃ"</string>
     <string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
     <string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
-    <string name="minute" msgid="9148878657703769868">"នាទី​"</string>
+    <string name="minute" msgid="9148878657703769868">"នាទី"</string>
     <string name="minutes" msgid="5646001005827034509">"នាទី"</string>
-    <string name="second" msgid="3184235808021478">"វិនាទី​"</string>
+    <string name="second" msgid="3184235808021478">"វិនាទី"</string>
     <string name="seconds" msgid="3161515347216589235">"វិនាទី"</string>
-    <string name="week" msgid="5617961537173061583">"សប្ដាហ៍​"</string>
-    <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍​"</string>
-    <string name="year" msgid="4001118221013892076">"ឆ្នាំ​"</string>
-    <string name="years" msgid="6881577717993213522">"ឆ្នាំ​"</string>
+    <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+    <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+    <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+    <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
   <plurals name="duration_seconds">
     <item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
     <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
@@ -1226,12 +1226,12 @@
     <string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហា​វីដេអូ"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូ​នេះ​មិន​ត្រឹមត្រូវ​សម្រាប់​​ចរន្ត​ចូល​ឧបករណ៍​នេះ។"</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិន​អាច​ចាក់​វីដេអូ​នេះ។"</string>
-    <string name="VideoView_error_button" msgid="2822238215100679592">"យល់​ព្រម​"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"យល់​ព្រម"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"រសៀល"</string>
     <string name="Noon" msgid="3342127745230013127">"រសៀល"</string>
     <string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
-    <string name="Midnight" msgid="5630806906897892201">"កណ្ដាល​អធ្រាត្រ​"</string>
+    <string name="Midnight" msgid="5630806906897892201">"កណ្ដាល​អធ្រាត្រ"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"ជ្រើស​ទាំងអស់"</string>
@@ -1248,14 +1248,14 @@
     <string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាព​អត្ថបទ"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់​ទំហំ​ផ្ទុក"</string>
-    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ​"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"មិន​មាន​ទំហំ​ផ្ទុក​​គ្រប់​គ្រាន់​សម្រាប់​ប្រព័ន្ធ​។ សូម​ប្រាកដ​ថា​អ្នក​មាន​ទំហំ​ទំនេរ​ 250MB ហើយ​ចាប់ផ្ដើម​ឡើង​វិញ។"</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"ប៉ះ​ ដើម្បី​មើល​ព័ត៌មាន​បន្ថែម ឬ​បញ្ឈប់​កម្មវិធី។"</string>
-    <string name="ok" msgid="5970060430562524910">"យល់​ព្រម​"</string>
-    <string name="cancel" msgid="6442560571259935130">"បោះ​បង់​"</string>
-    <string name="yes" msgid="5362982303337969312">"យល់​ព្រម​"</string>
-    <string name="no" msgid="5141531044935541497">"បោះ​បង់​"</string>
+    <string name="ok" msgid="5970060430562524910">"យល់​ព្រម"</string>
+    <string name="cancel" msgid="6442560571259935130">"បោះ​បង់"</string>
+    <string name="yes" msgid="5362982303337969312">"យល់​ព្រម"</string>
+    <string name="no" msgid="5141531044935541497">"បោះ​បង់"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"ប្រយ័ត្ន"</string>
     <string name="loading" msgid="7933681260296021180">"កំពុង​ផ្ទុក..."</string>
     <string name="capital_on" msgid="1544682755514494298">"បើក"</string>
@@ -1275,7 +1275,7 @@
     <string name="alwaysUse" msgid="4583018368000610438">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​សកម្មភាព​នេះ។"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"ប្រើ​កម្មវិធី​ផ្សេង"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាត​លំនាំដើម​ក្នុង​ការកំណត់​ប្រព័ន្ធ &gt; កម្មវិធី &gt; ទាញ​យក។"</string>
-    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព​​"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើស​កម្មវិធី​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
     <string name="noApplications" msgid="2991814273936504689">"គ្មាន​កម្មវិធី​អាច​អនុវត្ត​សកម្មភាព​នេះ។"</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
@@ -1286,7 +1286,7 @@
     <string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិន​ឆ្លើយតប។\n\nតើ​អ្នក​ចង់​បិទ​វា?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិន​ឆ្លើយតប។ តើ​អ្នក​ចង់​បិទ​វា?"</string>
     <string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិន​ឆ្លើយតប។ \n\nតើ​អ្នក​ចង់​បិទ​វា​ឬ?"</string>
-    <string name="force_close" msgid="8346072094521265605">"យល់​ព្រម​"</string>
+    <string name="force_close" msgid="8346072094521265605">"យល់​ព្រម"</string>
     <string name="report" msgid="4060218260984795706">"រាយការណ៍"</string>
     <string name="wait" msgid="7147118217226317732">"រង់ចាំ"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"ទំព័រ​ក្លាយ​ជា​មិន​ឆ្លើយតប។\n\nតើ​អ្នក​​ចង់​បិទ​វា?"</string>
@@ -1371,7 +1371,7 @@
     <string name="sms_short_code_details" msgid="5873295990846059400">"វា "<b>"អាច​គិត​លុយ"</b>" លើ​គណនី​ចល័ត​របស់​អ្នក។"</string>
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"វា​នឹង​គិតលុយ​គណនី​ចល័ត​របស់​អ្នក។"</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ផ្ញើ"</string>
-    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះ​បង់​"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះ​បង់"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ចងចាំ​ជម្រើស​របស់​ខ្ញុំ"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"អ្នក​អាច​ប្ដូរ​វា​ពេល​ក្រោយ​ក្នុង​ការ​កំណត់ &gt; កម្មវិធី"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាត​ជា​និច្ច"</string>
@@ -1382,8 +1382,8 @@
     <string name="sim_added_title" msgid="3719670512889674693">"បាន​បន្ថែម​ស៊ីម​កាត"</string>
     <string name="sim_added_message" msgid="7797975656153714319">"ចាប់ផ្ដើម​ឧបករណ៍​របស់​អ្នក​ឡើងវិញ ដើម្បី​ចូល​ប្រើ​បណ្ដាញ​ចល័ត។"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើម​ឡើងវិញ"</string>
-    <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់​ម៉ោង​"</string>
-    <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់​កាល​បរិច្ឆេទ​"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់​ម៉ោង"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់​កាល​បរិច្ឆេទ"</string>
     <string name="date_time_set" msgid="5777075614321087758">"កំណត់"</string>
     <string name="date_time_done" msgid="2507683751759308828">"រួចរាល់"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"ថ្មី៖ "</font></string>
@@ -1461,7 +1461,7 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យ​កម្មវិធី​ដក​សេវាកម្ម​នៃ​កម្មវិធី​ផ្ទុក​​លំនាំដើម ដើម្បី​ចម្លង​មាតិកា។​ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​លំនាំដើម។"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យ​កម្មវិធី​នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ​ទៅ​ឧបករណ៍​​ខាង​ក្រៅ​ផ្សេង។"</string>
-    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​សុវត្ថិភាព​"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​សុវត្ថិភាព"</string>
     <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យ​កម្មវិធី​ចូល​​ការ​ផ្ទុក​មាន​សុវត្ថិភាព keguard ។"</string>
     <string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យ​ការ​បង្ហាញ និង​លាក់​ការ​ការពារ"</string>
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង keguard ។"</string>
@@ -1484,7 +1484,7 @@
     <string name="ime_action_go" msgid="8320845651737369027">"ទៅ"</string>
     <string name="ime_action_search" msgid="658110271822807811">"ស្វែងរក"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"ផ្ញើ"</string>
-    <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់​"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"រួចរាល់"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"មុន"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"អនុវត្ត"</string>
@@ -1493,7 +1493,7 @@
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធី​មួយ ឬ​ច្រើន​ដូច​ខាង​ក្រោម​ស្នើ​សិទ្ធិ ដើម្បី​ចូល​គណនី​របស់​អ្នក​ឥឡូវ និង​ពេល​អនាគត។"</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"តើ​អ្នក​ចង់​អនុញ្ញាត​សំណើ​នេះ?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"ស្នើ​ចូល"</string>
-    <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត​"</string>
+    <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
     <string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"បាន​ស្នើ​សិទ្ធិ"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"បាន​ស្នើ​សិទ្ធិ\nសម្រាប់​គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</string>
@@ -1518,12 +1518,12 @@
     <string name="no_file_chosen" msgid="6363648562170759465">"គ្មាន​ឯកសារ​បាន​ជ្រើស"</string>
     <string name="reset" msgid="2448168080964209908">"កំណត់​ឡើងវិញ"</string>
     <string name="submit" msgid="1602335572089911941">"ដាក់​ស្នើ"</string>
-    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បាន​បើក​របៀប​រថយន្ត​"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បាន​បើក​របៀប​រថយន្ត"</string>
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ប៉ះ​ ដើម្បី​ចេញ​ពី​របៀប​រថយន្ត​។"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ​ ដើម្បី​រៀបចំ។"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
-    <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់​"</string>
+    <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
     <string name="no_matches" msgid="8129421908915840737">"គ្មាន​ការ​ផ្គូផ្គង"</string>
     <string name="find_on_page" msgid="1946799233822820384">"រក​ក្នុង​ទំព័រ"</string>
@@ -1545,7 +1545,7 @@
     <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​បច្ចុប្បន្ន​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ។"</string>
     <string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្ន​កាត​អេសឌី​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ"</string>
     <string name="media_unknown_state" msgid="729192782197290385">"មិន​ស្គាល់​ស្ថានភាព​មេឌៀ​ខាង​ក្រៅ។"</string>
-    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក​"</string>
+    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក"</string>
     <string name="find" msgid="4808270900322985960">"រក"</string>
     <string name="websearch" msgid="4337157977400211589">"ស្វែងរក​តាម​បណ្ដាញ"</string>
     <string name="find_next" msgid="5742124618942193978">"រក​បន្ទាប់"</string>
@@ -1561,7 +1561,7 @@
     <string name="sync_undo_deletes" msgid="2941317360600338602">"មិន​ធ្វើ​ការ​លុប​វិញ"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"មិន​ធ្វើអ្វី​ទេ​ឥឡូវ"</string>
     <string name="choose_account_label" msgid="5655203089746423927">"ជ្រើស​គណនី"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"បន្ថែម​គណនី​ថ្មី​​"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"បន្ថែម​គណនី​ថ្មី"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែម​គណនី"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
@@ -1580,15 +1580,15 @@
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើន​​ឆ្នាំ"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយ​ឆ្នាំ"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះ​បង់​"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះ​បង់"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូរ​របៀប"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើស​កម្មវិធី​​"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើស​កម្មវិធី"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"មិន​អាច​ចាប់ផ្ដើម <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែក​ជា​មួយ​"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែក​ជា​មួយ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែក​រំលែក​ជា​មួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រង​ការ​រុញ។ ប៉ះ &amp; សង្កត់។"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស​ ដើម្បី​ដោះ​សោ។"</string>
@@ -1602,7 +1602,7 @@
     <string name="storage_internal" msgid="4891916833657929263">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"កាត​អេសឌី"</string>
     <string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល​"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមាន​ប្រើ​ទិន្នន័យ"</string>
     <string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បី​មើល​ការ​ប្រើ និង​ការ​កំណត់។"</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"បាន​ដល់​ដែន​កំណត់​ទិន្នន័យ 2G-3G"</string>
@@ -1661,7 +1661,7 @@
     <string name="media_route_status_available" msgid="6983258067194649391">"ទំនេរ"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"មិន​ទំនេរ"</string>
     <string name="media_route_status_in_use" msgid="4533786031090198063">"កំពុង​ប្រើ"</string>
-    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់​ជាប់​"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់​ជាប់"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"អេក្រង់ HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួត​គ្នា"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
@@ -1688,7 +1688,7 @@
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បី​ដោះ​សោ ចូល​ក្នុង​គណនី Google ។"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះ​អ្នក​ប្រើ (អ៊ីមែល​)"</string>
-    <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់​"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេច​ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​របស់​អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -1801,7 +1801,7 @@
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
     <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"​មិន​ស្គាល់​បញ្ឈរ"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"មិន​ស្គាល់​ទេសភាព"</string>
-    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់​"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុស​ក្នុង​ការ​សរសេរ​មាតិកា"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"មិន​ស្គាល់"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"មិន​បា​ន​បើក​សេវាកម្ម​បោះពុម្ព"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 95c05d5..f811c85 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -770,7 +770,7 @@
     <string name="permdesc_use_sip" msgid="2297804849860225257">"ອະນຸຍາດ​ໃຫ້ແອັບຯ​ສາມາດ​ຮັບສາຍ ແລະໂທອອກ​ຜ່ານ SIP ໄດ້"</string>
     <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"ລົງ​ທະ​ບຽນ SIM ການ​ເຊື່ອມ​ຕໍ່​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມ​ໃໝ່"</string>
     <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ລົງ​ທະ​ບຽນ SIM ​ການ​ເຊື່ອມ​ຕໍ່​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມ​ໃໝ່."</string>
-    <string name="permlab_register_call_provider" msgid="108102120289029841">"ລົງ​ທະ​ບຽນການ​ເຊື່ອມ​ຕໍ່​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມໃໝ່​"</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"ລົງ​ທະ​ບຽນການ​ເຊື່ອມ​ຕໍ່​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມໃໝ່"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ລົງ​ທະ​ບຽນການ​ເຊື່ອມ​ຕໍ່​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມໃໝ່​."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"ຈັດ​ການ​ການ​ເຊື່ອມ​ຕໍ່​​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມ"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"​ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ຈັດ​ການ​ການ​ເຊື່ອມ​ຕໍ່​​ໂທ​ລະ​ຄົມ​ມະ​ນາ​ຄົມ."</string>
@@ -1811,7 +1811,7 @@
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະ​ຈຸ​ບັນ"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</string>
-    <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາ​ລັບ​ການ​ປັບ​ປຸງ​ຂໍ້ຈໍາ​ກັດ​"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາ​ລັບ​ການ​ປັບ​ປຸງ​ຂໍ້ຈໍາ​ກັດ"</string>
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ບໍ່​ກົງກັນ. ລອງໃໝ່ອີກຄັ້ງ​."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ​ສັ້ນ​ເກີນ​ໄປ​. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ​."</string>
   <plurals name="restr_pin_countdown">
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 1922b1b..8fe60c7 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -35,10 +35,10 @@
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> နာရီ <xliff:g id="MINUTES">%2$d</xliff:g> မိနစ်"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ်"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
-    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> မိနစ် <xliff:g id="SECONDS">%2$d</xliff:g> စက္ကန့်"</string>
+    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
+    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> စက္ကန့်"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;ခေါင်းစဉ်မဲ့&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -47,7 +47,7 @@
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"အသံစာပို့စနစ်"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"ဆက်သွယ်မှုဆိုင်ရာပြသနာ သို့မဟုတ် မမှန်ကန်သောMMIကုတ်"</string>
-    <string name="mmiFdnError" msgid="5224398216385316471">"သတ်မှတ်ခေါ်ဆိုနိုင်သောနံပါတ်များထံသာ ကန့်သတ်ထားသည်"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"သတ်မှတ်ခေါ်ဆိုနိုင်သောနံပါတ်များထံသာ ကန့်သတ်ထားသည်"</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"ဝန်ဆောင်မှု လုပ်ဆောင်နိုင်မည်"</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"ဝန်ဆောင်မှု ရရှိမည်"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"ဝန်ဆောင်မှုအား ရပ်ဆိုင်းသည်"</string>
@@ -57,10 +57,10 @@
     <string name="mmiComplete" msgid="8232527495411698359">"MMI ပြီးဆုံးပါပြီ"</string>
     <string name="badPin" msgid="9015277645546710014">"သင် ရိုက်ထည့်သော PIN ဟောင်းမှာ မမှန်ပါ။"</string>
     <string name="badPuk" msgid="5487257647081132201">"သင်ရိုက် ထည့်သော PUK မှာ မမှန်ကန်ပါ။"</string>
-    <string name="mismatchPin" msgid="609379054496863419">"သင် ရိုက်ထည့်ခဲ့သည့် PIN များ မတိုက်ဆိုင်ပါ။"</string>
-    <string name="invalidPin" msgid="3850018445187475377">"နံပါတ်(၄)ခုမှ(၈)ခုအထိပါရှိသော ပင်နံပါတ်အားထည့်ပါ"</string>
-    <string name="invalidPuk" msgid="8761456210898036513">"နံပါတ်(၈)ခုသို့မဟုတ် ထိုထက်ရှည်သောသော PUKအားထည့်သွင်းပါ"</string>
-    <string name="needPuk" msgid="919668385956251611">"ဆင်းမ်ကဒ် ရဲ့ ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ် သော့ကျနေပါသည်။ ဖွင့်ရန် ကုဒ်အားထည့်သွင်းပါ။"</string>
+    <string name="mismatchPin" msgid="609379054496863419">"သင် ရိုက်ထည့်ခဲ့သည့် PIN များ မတိုက်ဆိုင်ပါ။"</string>
+    <string name="invalidPin" msgid="3850018445187475377">"နံပါတ်(၄)ခုမှ(၈)ခုအထိပါရှိသော ပင်နံပါတ်အားထည့်ပါ"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"နံပါတ်(၈)ခုသို့မဟုတ် ထိုထက်ရှည်သောသော PUKအားထည့်သွင်းပါ"</string>
+    <string name="needPuk" msgid="919668385956251611">"ဆင်းမ်ကဒ် ရဲ့ ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ် သော့ကျနေပါသည်။ ဖွင့်ရန် ကုဒ်အားထည့်သွင်းပါ။"</string>
     <string name="needPuk2" msgid="4526033371987193070">"ဆင်းမ်ကဒ်အားမပိတ်ရန် PUK2အားထည့်သွင်းပါ"</string>
     <string name="enablePin" msgid="209412020907207950">"မအောင်မြင်ပါ, SIM/RUIM သော့ကို အရင် သုံးခွင့်ပြုရန်"</string>
   <plurals name="pinpuk_attempts">
@@ -73,24 +73,24 @@
     <string name="ClirMmi" msgid="7784673673446833091">"အထွက်ခေါ်ဆိုခြင်းအိုင်ဒီ"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"လိုင်း ID ချိတ်ဆက်သည်"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"လိုင်း ID ချိတ်ဆက်မှု ကန့်သတ်ချက်များ"</string>
-    <string name="CfMmi" msgid="5123218989141573515">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
-    <string name="CwMmi" msgid="9129678056795016867">"ခေါ်ဆိုမှု စောင့်ဆိုင်းခြင်း"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"ခေါ်ဆိုမှု စောင့်ဆိုင်းခြင်း"</string>
     <string name="BaMmi" msgid="455193067926770581">"အဝင်ခေါ်ဆိုမှုအားတားဆီးခြင်း"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"လျှို့ဝှက်နံပါတ်/စာ ပြောင်းသည်"</string>
     <string name="PinMmi" msgid="3113117780361190304">"ပင်နံပါတ်ပြောင်းသည်"</string>
     <string name="CnipMmi" msgid="3110534680557857162">"ခေါ်ဆိုသောနံပါတ်တည်ရှိသည်"</string>
-    <string name="CnirMmi" msgid="3062102121430548731">"ခေါ်ဆိုသောနံပါတ်အားကန့်သတ်ခြင်း"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"ခေါ်ဆိုသောနံပါတ်အားကန့်သတ်ခြင်း"</string>
     <string name="ThreeWCMmi" msgid="9051047170321190368">"(၃)ယောက်ဆိုင်ပြောဆိုခြင်း"</string>
-    <string name="RuacMmi" msgid="7827887459138308886">"စိတ်အနှောက်အယှက်ဖြစ်သော မလိုလားသည့်ခေါ်ဆိုမှုများအား ငြင်းဖယ်ခြင်း"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"စိတ်အနှောက်အယှက်ဖြစ်သော မလိုလားသည့်ခေါ်ဆိုမှုများအား ငြင်းဖယ်ခြင်း"</string>
     <string name="CndMmi" msgid="3116446237081575808">"ခေါ်ဆိုသောနံပါတ် ပေးပို့မှု"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"မနှောက်ယှက်ပါနှင့်"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်မထားပါ။"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်မထားပါ။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်မထားပါ။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်မထားပါ။"</string>
-    <string name="serviceNotProvisioned" msgid="8614830180508686666">"ဝန်ဆောင်မှုအား ကန့်သတ်မထားပါ"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"မနှောက်ယှက်ပါနှင့်"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်မထားပါ။"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်မထားပါ။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်မထားပါ။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်မထားပါ။"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"ဝန်ဆောင်မှုအား ကန့်သတ်မထားပါ"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"သင်သည် ခေါ်ဆိုသူ ID ဆက်တင်ကို မပြောင်းလဲနိုင်ပါ။"</string>
-    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"ဝင်ရောက်ကြည့်ရှုခြင်းကန့်သတ်ချက်အားပြောင်းထားသည်"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"ဝင်ရောက်ကြည့်ရှုခြင်းကန့်သတ်ချက်အားပြောင်းထားသည်"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"ဒေတာဝန်ဆောင်မှုပိတ်ထားသည်။"</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"အရေးပေါ်ဝန်ဆောင်မှုပိတ်ထားသည်။"</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"အသံဝန်ဆောင်မှုပိတ်ထားသည်။"</string>
@@ -111,25 +111,25 @@
     <string name="serviceClassDataSync" msgid="7530000519646054776">"ထပ်တူ ကိုက်ညီခြင်း"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"Packet"</string>
     <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
-    <string name="roamingText0" msgid="7170335472198694945">"ရုန်းမင်းအချက်ပြမီး ဖွင့်ထားခြင်း"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"ရုန်းမင်းအချက်ပြမီး ဖွင့်ထားခြင်း"</string>
     <string name="roamingText1" msgid="5314861519752538922">"ရုန်းမင်းအချက်ပြမီး ပိတ်ထားခြင်း"</string>
     <string name="roamingText2" msgid="8969929049081268115">"ရုန်းမင်းအချက်ပြမီး လက်နေခြင်း"</string>
     <string name="roamingText3" msgid="5148255027043943317">"ပတ်ဝန်းကျင်အနီးအနားပြင်ပ"</string>
     <string name="roamingText4" msgid="8808456682550796530">"အဆောက်အဦးပြင်ပ"</string>
-    <string name="roamingText5" msgid="7604063252850354350">"ရုန်းမင်း-ပိုမိုသင့်တော်သောစနစ်"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"ရုန်းမင်း-ပိုမိုသင့်တော်သောစနစ်"</string>
     <string name="roamingText6" msgid="2059440825782871513">"ရုန်းမင်း-ရရှိနိုင်သောစနစ်"</string>
     <string name="roamingText7" msgid="7112078724097233605">"ရုန်းမင်း-ပူးပေါင်းလုပ်ဖော်ကိုင်ဖက်"</string>
     <string name="roamingText8" msgid="5989569778604089291">"ရုန်းမင်း-အထူးတန်ဖိုးထားရသောလုပ်ဖော်ကိုင်ဖက်"</string>
-    <string name="roamingText9" msgid="7969296811355152491">"ရုန်းမင်း-ဝန်ဆောင်မှုအပြည့်လုပ်ဆောင်မှု"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"ရုန်းမင်း-ဝန်ဆောင်မှုအပြည့်လုပ်ဆောင်မှု"</string>
     <string name="roamingText10" msgid="3992906999815316417">"ရုန်းမင်း-ဝန်ဆောင်မှုတစိတ်တပိုင်းလုပ်ဆောင်မှု"</string>
-    <string name="roamingText11" msgid="4154476854426920970">"ရုန်းမင်းစာတမ်းဖွင့်ရန်"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"ရုန်းမင်းစာတမ်းဖွင့်ရန်"</string>
     <string name="roamingText12" msgid="1189071119992726320">"ရုန်းမင်းစာတမ်းပိတ်ထားရန်"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"ဆားဗစ်အားရှာဖွေနေသည်"</string>
-    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
-    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> နောက် <xliff:g id="TIME_DELAY">{2}</xliff:g> စက္ကန့်"</string>
-    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
-    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> နောက် <xliff:g id="TIME_DELAY">{2}</xliff:g> စက္ကန့်"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
     <string name="fcComplete" msgid="3118848230966886575">"ပုံစံကုတ်ပြီးဆုံးသည်"</string>
     <string name="fcError" msgid="3327560126588500777">"ဆက်သွယ်မှုဆိုင်ရာပြသနာ သို့မဟုတ် တရားမဝင်သောပုံစံကုတ်"</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ကောင်းပြီ"</string>
@@ -137,11 +137,11 @@
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL ကို ရှာဖွေ့ မတွေ့ရှိပါ"</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"ဆိုက် မှန်ကန်မှု စိစစ်ရေး စနစ်ကို ပံ့ပိုး မပေးပါ။"</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"စစ်ဆေးမှု မအောင်မြင်ပါ"</string>
-    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"ပရိုစီဆာဗာမှတဆင့် အထောက်အထားပြခြင်းမအောင်မြင်ပါ"</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"ပရိုစီဆာဗာမှတဆင့် အထောက်အထားပြခြင်းမအောင်မြင်ပါ"</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"ဆာဗာကို ဆက်သွယ်လို့ မရပါ"</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"ဆာဗာနဲ့ ဆက်သွယ်လို့ မရပါ။ နောက်မှ ပြန်လည်ကြိုးစားပါ"</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"ဆာဗာအားဆက်သွယ်မှု အချိန်ကုန်ဆုံးသွားပါသည်"</string>
-    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"ဤစာမျက်နှာတွင် ဆာဗာအားတဆင့်လွှဲမှု များစွာပါဝင်သည်"</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"ဤစာမျက်နှာတွင် ဆာဗာအားတဆင့်လွှဲမှု များစွာပါဝင်သည်"</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"ပရိုတိုကောကို ပံ့ပိုး မပေးပါ။"</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"လုံခြုံစိတ်ချရသော ဆက်သွယ်မှု မရပါ"</string>
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL က အမှန်အကန် မဟုတ်သောကြောင့် စာမျက်နှာကို ဖွင့် လို့ မရပါ"</string>
@@ -153,23 +153,23 @@
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"ထပ်တူ ကိုက်ညီခြင်း"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"ဖျက်ရန် <xliff:g id="CONTENT_TYPE">%s</xliff:g> များစွာရှိ"</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"တက်ဘလက်တွင် သိမ်းဆည်းသော နေရာ ကုန်သွားပါပြီ။ တချို့ ဖိုင်များ ဖျက်စီးခြင်းဖြင့် နေရာလွတ် ပြုလုပ်ပါ"</string>
-    <string name="low_memory" product="watch" msgid="4415914910770005166">"သိုလှောင်ခန်း နေရာ ပြည့်နေပြီ။ နေရာ လွတ်လာရန် ဖိုင် အချို့ကို ဖျက်ပါ။"</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"သိုလှောင်ခန်း နေရာ ပြည့်နေပြီ။ နေရာ လွတ်လာရန် ဖိုင် အချို့ကို ဖျက်ပါ။"</string>
     <string name="low_memory" product="tv" msgid="516619861191025923">"တီဗွီ၏ သိုလှောင်ရုံ ပြည့်နေ၏။ နေရာလွတ်ရရန် ဖိုင်တစ်ချို့အား ဖျက်ပစ်ပါ။"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"ဖုန်းတွင် သိမ်းဆည်းသော နေရာ ကုန်သွားပါပြီ။ တချို့ ဖိုင်များ ဖျက်စီးခြင်းဖြင့် နေရာလွတ် ပြုလုပ်ပါ"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ကွန်ရက်ကို စောင့်ကြည့်စစ်ဆေးခံရနိုင်သည်"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"အမျိုးအမည်မသိ တတိယ ပါတီဖြင့်"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> ဖြင့်"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"အလုပ်ပရိုဖိုင် ဖျက်ပြီးဖြစ်၏"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"အက်ဒမင် အပလီကေးရှင်း ပျောက်နေသောကြောင့် အလုပ်ပရိုဖိုင် ပျက်သွားသည်။"</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"အလုပ်ပရိုဖိုင် အက်ဒမင် အပလီကေးရှင်းပျောက်နေသည် သို့မဟုတ် ပျက်စီးနေသည်။ ထို့ကြောင့် သင့်အလုပ်ပရိုဖိုင်နှင့် ဆက်စပ်နေသော ဒေတာများအား ပယ်ဖျက်ခြင်းခံရမည်။ အကူအညီတောင်းခံရန် သင့်အက်ဒမင်အား ဆက်သွယ်ပါ။"</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"အက်ဒမင် အပလီကေးရှင်း၏ အစိတ်အပိုင်းများ ပျောက်နေသည် သို့မဟုတ် ပျက်စီးနေသည်။ သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်။ အကူအညီတောင်းခံရန် သင့်အက်ဒမင်အား ဆက်သွယ်ပါ။"</string>
+    <string name="work_profile_deleted_description" msgid="6305147513054341102">"အက်ဒမင် အပလီကေးရှင်း ပျောက်နေသောကြောင့် အလုပ်ပရိုဖိုင် ပျက်သွားသည်။"</string>
+    <string name="work_profile_deleted_details" msgid="226615743462361248">"အလုပ်ပရိုဖိုင် အက်ဒမင် အပလီကေးရှင်းပျောက်နေသည် သို့မဟုတ် ပျက်စီးနေသည်။ ထို့ကြောင့် သင့်အလုပ်ပရိုဖိုင်နှင့် ဆက်စပ်နေသော ဒေတာများအား ပယ်ဖျက်ခြင်းခံရမည်။ အကူအညီတောင်းခံရန် သင့်အက်ဒမင်အား ဆက်သွယ်ပါ။"</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
+    <string name="factory_reset_message" msgid="4905025204141900666">"အက်ဒမင် အပလီကေးရှင်း၏ အစိတ်အပိုင်းများ ပျောက်နေသည် သို့မဟုတ် ပျက်စီးနေသည်။ သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်။ အကူအညီတောင်းခံရန် သင့်အက်ဒမင်အား ဆက်သွယ်ပါ။"</string>
     <string name="me" msgid="6545696007631404292">"ကျွန်ုပ်"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletဆိုင်ရာရွေးချယ်မှုများ"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"တီဗွီ ရွေးချယ်စရာများ"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"ဖုန်းဆိုင်ရာရွေးချယ်မှုများ"</string>
     <string name="silent_mode" msgid="7167703389802618663">"အသံတိတ်စနစ်"</string>
-    <string name="turn_on_radio" msgid="3912793092339962371">"wirelessအားဖွင့်မည်"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"wirelessအားဖွင့်မည်"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"wirelessအားပိတ်မည်"</string>
     <string name="screen_lock" msgid="799094655496098153">"ဖုန်းမျက်နှာပြင်အား သော့ချရန်"</string>
     <string name="power_off" msgid="4266614107412865048">"စက်ပိတ်ပါ"</string>
@@ -177,10 +177,10 @@
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"တုန်ခါခြင်း ဖုန်းမြည်သံ"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"ဖုန်းမြည်သံဖွင့်ထားသည်"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"စက်ပိတ်ပါမည်"</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"သင့်တက်ဘလက်အား စက်ပိတ်ပါမည်"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"သင့်တက်ဘလက်အား စက်ပိတ်ပါမည်"</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"တီဗွီ ပိတ်သွားမည်။"</string>
-    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"သင်၏ ကြည့်ရှုမှု ပိတ်ပစ်မည်။"</string>
-    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"သင့်ဖုန်းအား စက်ပိတ်ပါမည်"</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"သင်၏ ကြည့်ရှုမှု ပိတ်ပစ်မည်။"</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"သင့်ဖုန်းအား စက်ပိတ်ပါမည်"</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"သင်က ပိတ်ပစ်မှာကို လိုပါသလား?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"safe mode ဖြင့် ပြန်လည် စ တင်ရန်"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"safe mode ကို ပြန်လည် စတင် မလား? ဒီလို စတင်ခြင်းဟာ သင် သွင်းထားသော တတိယပါတီ အပလီကေးရှင်းများအား ရပ်ဆိုင်းထားပါမည်။ ပုံမှန်အတိုင်း ပြန်စလျှင် ထိုအရာများ ပြန်လည် ရောက်ရှိလာပါမည်။"</string>
@@ -196,9 +196,9 @@
     <string name="bugreport_message" msgid="398447048750350456">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"အသံတိတ်စနစ်"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"အသံပိတ်ထားသည်"</string>
-    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"အသံဖွင့်ထားသည်"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"အသံဖွင့်ထားသည်"</string>
     <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်"</string>
-    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"လေယဥ်ပျံပေါ်၌အသုံးပြုသောစနစ်ဖွင့်ထားသည်"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"လေယဥ်ပျံပေါ်၌အသုံးပြုသောစနစ်ဖွင့်ထားသည်"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"လေယဥ်ပျံပေါ်၌အသုံးပြုသောစနစ်ပိတ်ထားသည်"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"ဆက်တင်များ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string>
@@ -209,13 +209,13 @@
     <string name="managed_profile_label" msgid="6260850669674791528">"အလုပ်"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"သင်ငွေကုန်ကျမည်ဖြစ်သောဝန်ဆောင်မှုများ"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"သင်ပိုက်ဆံကုန်ကျစေသော အရာများ ပြုလုပ်ခြင်း"</string>
-    <string name="permgrouplab_messages" msgid="7521249148445456662">"သင့်စာများ"</string>
-    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Read and write သင်၏ စာတို၊ အီးမေးလ်၊ နှင့် အခြား စာများကို ဖတ်ခြင်း နှင့် ရေးခြင်း။"</string>
-    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"သင့်ကိုယ်ပိုင်ရေးရာအချက်အလက်များ"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"သင့်စာများ"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Read and write သင်၏ စာတို၊ အီးမေးလ်၊ နှင့် အခြား စာများကို ဖတ်ခြင်း နှင့် ရေးခြင်း။"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"သင့်ကိုယ်ပိုင်ရေးရာအချက်အလက်များ"</string>
     <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"အဆက်အသွယ်ကဒ်ထဲ၌ သိမ်းဆည်းထားသော သင့် သတင်းအချက်အလက်များအား တိုက်ရိုက်အသုံးပြုခွင့် ရယူရန်"</string>
     <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"သင်၏ ဆိုရှယ် သတင်းအချက်အလက်"</string>
     <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"သင်၏ အဆက်အသွယ်များနှင့် ဆိုရှယ်လ် အဆက်အသွယ်များအား၏ သတင်းအချက်အလက်များအား တိုက်ရိုက်အသုံးပြုခွင့် ရယူရန်"</string>
-    <string name="permgrouplab_location" msgid="635149742436692049">"သင့်တည်နေရာ"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"သင့်တည်နေရာ"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"သင် ရောက်ရှိနေသော တည်နေရာကို စောင့်ကြည့်ခြင်း"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"ကွန်ယက်ဆက်သွယ်မှု"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"ကွန်ရက် စွမ်းဆောင်ချက် အမျိုးမျိုးအသုံးပြုခွင့်ပေးရန်"</string>
@@ -253,16 +253,16 @@
     <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"စက်ရဲ့ အခြေအနေပြ ဘား ဆက်တင်အား ပြင်ဆင်ရန်"</string>
     <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"ထပ်တူပြုဆက်တင်များ"</string>
     <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"ထပ်တူညီအောင်လုပ်ရန်ဆက်တင်အား အသုံးပြုခွင့်ပေးရန်"</string>
-    <string name="permgrouplab_accounts" msgid="3359646291125325519">"သင့်အကောင့်များ"</string>
-    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ရရိှနိုင်သောအကောင့်များကို အသုံးပြုရန်"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"သင့်အကောင့်များ"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ရရိှနိုင်သောအကောင့်များကို အသုံးပြုရန်"</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"စက်ပစ္စည်းအား ထိန်းချုပ်ရန်"</string>
     <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ဖုန်း၏ စက်ပိုင်းဆိုင်ရာကို တိုက်ရိုက်ဝင်ရောက်ရန်"</string>
     <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"ဖုန်းခေါ်ဆိုမှုများ"</string>
-    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"ဖုန်းခေါ်ဆိုမှုများကို စောင့်ကြည့်စစ်ဆေးခြင်း၊ မှတ်တမ်းတင်ခြင်းနှင့် စီမံခြင်း"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"ဖုန်းခေါ်ဆိုမှုများကို စောင့်ကြည့်စစ်ဆေးခြင်း၊ မှတ်တမ်းတင်ခြင်းနှင့် စီမံခြင်း"</string>
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"စစ်စတန်ကိရိယာများ"</string>
-    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"အဆင့်နိမ့်ဝင်ရောက်ကြည့်ခြင်းနှင့် စနစ်ကိုထိန်းချုပ်ခြင်း"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"အဆင့်နိမ့်ဝင်ရောက်ကြည့်ခြင်းနှင့် စနစ်ကိုထိန်းချုပ်ခြင်း"</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ဖွံ့ဖိြုးတိုးတက်မှုဆိုင်ရာ ကိရိယာများ"</string>
-    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"appကို တိုးတက်ပြုစုကြသူတို့သာ လိုအပ်နိုင်သည့် အင်္ဂါရပ်များ ဖြစ်သည်။"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"appကို တိုးတက်ပြုစုကြသူတို့သာ လိုအပ်နိုင်သည့် အင်္ဂါရပ်များ ဖြစ်သည်။"</string>
     <string name="permgrouplab_display" msgid="4279909676036402636">"တခြား အပလီကေးရှင်း အသွင်အပြင်"</string>
     <string name="permgroupdesc_display" msgid="6051002031933013714">"တခြားအပလီကေးရှင်းများရဲ့ အသွင်အပြင်ကို အကျိုးသက်ရောက်စေရန်"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"သိုလှောင်မှုများ"</string>
@@ -279,45 +279,45 @@
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ရိုက်သောစာများကို သေချာစွာ စစ်ဆေးပါ"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"အရေးကြီးသော ကိုယ်ရေးအချက်အလက်များဖြစ်တဲ့ ခရက်ဒစ်ကဒ်နံပါတ်များနှင့် စကားဝှက်များ ပါဝင်ပါတယ်."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"appအား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"appအား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"အခြေအနေပြနေရာ"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"appအား အခြေအနေပြ ဘားဖြစ်ခွင့် ပြုသည်။"</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"အခြေအနေပြဘားအား ချဲ့/ပြန့်ခြင်း"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"appအား အခြေအနေပြ ဘားကို ချဲ့ခွင့် သို့မဟုတ် ခေါက်သိမ်းခွင့် ပြုသည်။"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"appအား အခြေအနေပြ ဘားဖြစ်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"အခြေအနေပြဘားအား ချဲ့/ပြန့်ခြင်း"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"appအား အခြေအနေပြ ဘားကို ချဲ့ခွင့် သို့မဟုတ် ခေါက်သိမ်းခွင့် ပြုသည်။"</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"အတိုကောက်များအား ထည့်သွင်းခြင်း"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ပြောင်းလဲခွင့် ပေးခြင်း"</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"အတိုကောက်များ ဖယ်ထုတ်ခြင်း"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ဖယ်ရှားခွင့် ပေးခြင်း"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"အထွက် ခေါ်ဆိုမှုများအား လမ်းလွှဲပြောင်းခြင်း"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"appအား အပြင်သို့ ဖုန်းခေါ်ဆိုမှု အတွင်းမှာ ဆက်ခဲ့သည့် နံပါတ်ကို ကြည့်နိုင်ကာ ခေါ်ဆိုမှုကို အခြား နံပါတ် တစ်ခုသို့ ပြောင်းလဲပစ်ခြင်း သို့မဟုတ် ခေါ်ဆိုမှုကို လုံးဝ ဖျက်သိမ်းခွင့် ပြုသည်။"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"appအား အပြင်သို့ ဖုန်းခေါ်ဆိုမှု အတွင်းမှာ ဆက်ခဲ့သည့် နံပါတ်ကို ကြည့်နိုင်ကာ ခေါ်ဆိုမှုကို အခြား နံပါတ် တစ်ခုသို့ ပြောင်းလဲပစ်ခြင်း သို့မဟုတ် ခေါ်ဆိုမှုကို လုံးဝ ဖျက်သိမ်းခွင့် ပြုသည်။"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"စာပို့ခြင်းအား လက်ခံရယူခြင်း (စာတိုစနစ်)"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"အပလီကေးရှင်းအား စာတိုများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"အပလီကေးရှင်းအား စာတိုများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"စာပို့ခြင်းအား လက်ခံရယူခြင်း (ရုပ်သံစာ)"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"အပလီကေးရှင်းအား ရုပ်သံစာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
-    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"အရေးပေါ်ထုတ်လွှင့်မှုများ လက်ခံခြင်း"</string>
-    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"appအား အရေးပေါ် ထုတ်လွှင့်သည့် စာများကို လက်ခံလျက် စီမံဆောင်ရွက်ခွင့် ပြုသည်။ ယင်း ခွင့်ပြုချက်မှာ စနစ် appများ အတွက်သာ ဖြစ်သည်။"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"အပလီကေးရှင်းအား ရုပ်သံစာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"အရေးပေါ်ထုတ်လွှင့်မှုများ လက်ခံခြင်း"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"appအား အရေးပေါ် ထုတ်လွှင့်သည့် စာများကို လက်ခံလျက် စီမံဆောင်ရွက်ခွင့် ပြုသည်။ ယင်း ခွင့်ပြုချက်မှာ စနစ် appများ အတွက်သာ ဖြစ်သည်။"</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"စာတိုများ ဖြန့်ဝေခြင်းစနစ်အား ဖတ်ခြင်း"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"အပလီကေးရှင်းကို သင်၏ စက်ပစ္စည်းမှ လက်ခံရရှိသော အများလွှင့်ထုတ်ချက်များကို ဖတ်ရန် ခွင့်ပြုသည်။  အများလွှင့်ထုတ်ချက်များသည် အရေးပေါ်အခြေအနေများကို သင့်အား သတိပေးရန် အချို့ နေရာများတွင် ပို့ပေးသည်။ အရေးပေါ်သတိပေးချက် ထုတ်လွှင့်ချက်ကို လက်ခံရရှိချိန်တွင်အန္တရာယ် ဖြစ်စေနိုင်သော အပလီကေးရှင်းများသည် သင့်စက်ပစ္စည်း၏ လုပ်ငန်းလည်ပတ်မှုနှင့် စွမ်းဆောင်မှုကို ဝင်စွက်ဖက်နိုင်သည်။"</string>
-    <string name="permlab_sendSms" msgid="5600830612147671529">"စာတိုပို့စနစ်(SMS)ဖြင့် စာများ ပို့သည်"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"စာတိုပို့စနစ်(SMS)ဖြင့် စာများ ပို့သည်"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"အပလီကေးရှင်းအား စာတိုပို့ခွင့် ပြုပါ။ မမျှော်လင့်သော ကုန်ကျမှု ဖြစ်နိုင်ပါသည်။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ သင် မသိပဲ စာပို့ခြင်းများ ပြုလုပ်ခြင်းကြောင့် ပိုက်ဆံ အပို ကုန်စေနိုင်သည်"</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"စာပြန်မှုခြင်း အသိပေးခြင်း များ ပြုလုပ်ခြင်း"</string>
     <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"အပလီကေးရှင်းအား တခြား စာအပြန်အလှန် ပို့ဆောင်မှု ပေးသော အပလီကေးရှင်းများဆီကို ဖုန်းခေါ်ဆိုမှု များအတွက် စာပို့ခြင်းဖြင့် ပြန်လည် ဖြေဆိုသော တောင်းဆိုမှု များ ခွင့်ပြုခြင်း"</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"သင့်ရဲ့ စာပေးပို့ခြင်းများ ဖတ်ခြင်း (စာတို နှင့် ရုပ်သံစာ)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"အပလီကေးရှင်းအား တက်ဘလက် သို့မဟုတ် ဆင်းမ်ကဒ်မှာ သိမ်းဆည်းထားသော စာတိုများ ဖတ်ရှုခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် အကြာင်းအရာ သို့မဟုတ် ယုံကြည်စိတ်ချရမှုကို ဂရုမပြုပဲ စာတိုအားလုံးကို ဖတ်နိုင်ပါလိမ်မည်။"</string>
-    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"သင့်တီဗွီ သို့မဟုတ် ဆင်းမ်ကဒ်တွင် သိမ်းထားသည့် SMS စာများကို app အား ဖတ်ခွင့်ပြုပါ။ ထိုသို့ခွင့်ပြုခြင်းဖြင့် app သည် အကြောင်းအရာ သို့မဟုတ် ယုံကြည်စိတ်ချရမှု တို့နှင့် မသက်ဆိုင်ဘဲ၊ SMS စာများအားလုံးကို ဖတ်နိုင်မည်ဖြစ်၏။"</string>
+    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"သင့်တီဗွီ သို့မဟုတ် ဆင်းမ်ကဒ်တွင် သိမ်းထားသည့် SMS စာများကို app အား ဖတ်ခွင့်ပြုပါ။ ထိုသို့ခွင့်ပြုခြင်းဖြင့် app သည် အကြောင်းအရာ သို့မဟုတ် ယုံကြည်စိတ်ချရမှု တို့နှင့် မသက်ဆိုင်ဘဲ၊ SMS စာများအားလုံးကို ဖတ်နိုင်မည်ဖြစ်၏။"</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"အပလီကေးရှင်းအား ဖုန်း သို့မဟုတ် ဆင်းမ်ကဒ်မှာ သိမ်းဆည်းထားသော စာတိုများ ဖတ်ရှုခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် အကြာင်းအရာ သို့မဟုတ် ယုံကြည်စိတ်ချရမှုကို ဂရုမပြုပဲ စာတိုအားလုံးကို ဖတ်နိုင်ပါလိမ်မည်။"</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"သင့်ရဲ့ စာပေးပို့ခြင်းများ ပြင်ခြင်း (စာတို နှင့် ရုပ်သံစာ)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"appအား သင်၏ တက်ဘလက် သို့မဟုတ် ဆင်းမ်ကဒ်ထဲမှာ သိုလှောင်ထားသည့် စာတိုများသို့ ရေးခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စာတိုမျာကို ဖျက်ပစ်နိုင်သည်။"</string>
-    <string name="permdesc_writeSms" product="tv" msgid="955871498983538187">"App အား သင့်တီဗွီ သို့မဟုတ် စင်းမ်ကဒ်တွင် သိမ်းထားသော SMS  စာတိုများကို ရေးခွင့်ပြုပါ။ အန္တရာယ်ရှိသော app များက သင့် စာတိုများအား ဖျက်ပစ်နိုင်သည်။"</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"appအား သင်၏ ဖုန်း သို့မဟုတ် ဆင်းမ်ကဒ်ထဲမှာ သိုလှောင်ထားသည့် စာတိုများသို့ ရေးခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စာတိုမျာကို ဖျက်ပစ်နိုင်သည်။"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"appအား သင်၏ တက်ဘလက် သို့မဟုတ် ဆင်းမ်ကဒ်ထဲမှာ သိုလှောင်ထားသည့် စာတိုများသို့ ရေးခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စာတိုမျာကို ဖျက်ပစ်နိုင်သည်။"</string>
+    <string name="permdesc_writeSms" product="tv" msgid="955871498983538187">"App အား သင့်တီဗွီ သို့မဟုတ် စင်းမ်ကဒ်တွင် သိမ်းထားသော SMS  စာတိုများကို ရေးခွင့်ပြုပါ။ အန္တရာယ်ရှိသော app များက သင့် စာတိုများအား ဖျက်ပစ်နိုင်သည်။"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"appအား သင်၏ ဖုန်း သို့မဟုတ် ဆင်းမ်ကဒ်ထဲမှာ သိုလှောင်ထားသည့် စာတိုများသို့ ရေးခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စာတိုမျာကို ဖျက်ပစ်နိုင်သည်။"</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"စာပို့ခြင်းအား လက်ခံရယူခြင်း (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"အပလီကေးရှင်းအား WAP စာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"အပလီကေးရှင်းအား WAP စာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
     <string name="permlab_receiveBluetoothMap" msgid="7593811487142360528">"Bluetooth စာများလက်ခံမည် (MAP)"</string>
     <string name="permdesc_receiveBluetoothMap" msgid="8656755936919466345">"Bluetooth MAP စာများကို app မှလက်ခံကာ အလုပ်လုပ်ရန် ခွင့်ပြင်မည်။ ဆိုလိုသည်မှာ app သည်သင့်အား မပြသဘဲ သင့်ကိရိယာသို့ပို့လိုက်သည့် စာများကို ထိန်းချုပ်နိုင် သို့မဟုတ် ဖျက်နိုင်ပါသည်။"</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"အလုပ်လုပ်နေကြသည့် appများကို ရယူခြင်း"</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"အလုပ်လုပ်နေကြသည့် appများကို ရယူခြင်း"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"အပလီကေးရှင်းအား လက်ရှိနဲ့ လတ်တလော လုပ်ဆောင်ခဲ့သော သတင်းအချက်အလက် အသေးစိတ်အား ထုတ်ယူခွင့်ပြုရန်။ အပလီကေးရှင်းမှ သင် ဘယ် အပလီကေးရှင်းများသုံးရှိကြောင့် တွေ့ရှိနိုင်ပါသည်"</string>
     <string name="permlab_startTasksFromRecents" msgid="8990073877885690623">"မကြာမီ ထဲက တာဝန် တစ်ခုကို စတင်ရန်"</string>
-    <string name="permdesc_startTasksFromRecents" msgid="7382133554871222235">"appအား တက်ကြွမန်နေဂျာ။မကြာမီတာဝန်အင်ဖို အရာကို သုံးပြီး တက်ကြွမန်နေဂျာ။မကြာမီတာဝန်စာရင်းရယူ() ထံမှ ပြန်လာခဲ့သည့် ရပ်စဲခံလိုက်ရသည့် တာဝန်ကို ဖွင့်တင်ရန် အတွက် သုံးခွင့်ပြုသည်။"</string>
+    <string name="permdesc_startTasksFromRecents" msgid="7382133554871222235">"appအား တက်ကြွမန်နေဂျာ။မကြာမီတာဝန်အင်ဖို အရာကို သုံးပြီး တက်ကြွမန်နေဂျာ။မကြာမီတာဝန်စာရင်းရယူ() ထံမှ ပြန်လာခဲ့သည့် ရပ်စဲခံလိုက်ရသည့် တာဝန်ကို ဖွင့်တင်ရန် အတွက် သုံးခွင့်ပြုသည်။"</string>
     <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"အသုံးပြုသူများအကြား ဆက်ဆံခြင်း"</string>
     <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"အပလီကေးရှင်းအား စက်ပေါ်ရှိ တစ်ယောက်ထက်ပိုသော အသုံးပြုသူများအတွက် လုပ်ဆောင်ချက်များ ပြုလုပ်ခွင့်ပေးပါ။ အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ဒီအရာကို သုံးပြီး အသုံးပြုသူများအတွင်း ကာကွယ်မှုကို ဖောက်ဖျက်နိုင်ပါသည်"</string>
     <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"အသုံးပြုသူများအကြား ဆက်ဆံရန် လိုင်စင် အပြည့်"</string>
@@ -326,9 +326,9 @@
     <string name="permdesc_manageUsers" msgid="8409306667645355638">"အပလီကေးရှင်းအား အသုံးပြုသူများကို စီမံခန့်ခွဲခွင့် ပေးပါ။ ဥပမာ ကြည့်ရှုခြင်း၊ အသစ်ပြုလုပ်ခြင်း၊ ဖျက်စီးခြင်း"</string>
     <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"သုံးနေသော အပလီကေးရှင်းများ၏ အချက်အလက် ရယူခြင်း"</string>
     <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"အပလီကေးရှင်းအား လက်ရှိနဲ့ လတ်တလော လုပ်ဆောင်ခဲ့သော သတင်းအချက်အလက် အသေးစိတ်အား ထုတ်ယူခွင့်ပြုရန်။ အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ တခြား အပလီကေးရှင်းများရဲ့ အတွင်းကျသော သတင်းအချက်အလက်များအား တွေ့ရှိနိုင်ပါသည်။"</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"အလုပ်လုပ်နေကြသည့် appများကို ပြန်လည်စီစဉ်ခြင်း"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"အလုပ်လုပ်နေကြသည့် appများကို ပြန်လည်စီစဉ်ခြင်း"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"အပလီကေးရှင်းအား နောက်ကွယ် နှင့် ရှေ့မှောက်တွင် လက်ရှိ လုပ်ဆောင်နေမှုများအား ဖယ်ခွင့် ပြုပါ။ သင့် ခွင့်ပြုချက်မပါပဲ လုပ်ဆောင်နိုင်ပါလိမ့်မည်"</string>
-    <string name="permlab_removeTasks" msgid="6821513401870377403">"အလုပ်လုပ်နေကြသည့် appများကို ရပ်ခြင်း"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"အလုပ်လုပ်နေကြသည့် appများကို ရပ်ခြင်း"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"အပလီကေးရှင်းအား စက်မှ လက်ရှိလုပ်ဆောင်နေမှုများအား ဖယ်ရှားခြင်းနှင့် ၎င်းတို့၏ အပလီကေးရှင်းများအား ရပ်တန့်စေရန် လုပ်ခွင့်ပြုပါ။ အန္တရာယ်ရှိ အပလီကေးရှင်းများက တခြား အပလီကေးရှင်းများ၏ အပြုအမူအား ဒုက္ခပေးနိုင်ပါသည်"</string>
     <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"လုပ်ဆောင်မှု စာရင်းများအား ထိန်းသိမ်းခြင်း"</string>
     <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"အပလီကေးရှင်းအား တခြားအပလီကေးရှင်းများမှ လုပ်ဆောင်ချက်များအား ထပ်ထည့်ခွင့်၊ ဖယ်ခွင့်၊ ပြင်ဆင်ခွင့် ပေးခြင်း။ စိတ်ချရမှု မရှိသော အပလီကေးရှင်းဆိုလျှင် တခြား အပလီကေးရှင်းများရဲ့ လုပ်ငန်းဆောင်ရွက်ချက်များအား မှားယွင်းစေနိုင်ပါသည်"</string>
@@ -336,48 +336,48 @@
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"ခွင့်ပြုချက်ကာကွယ်ခြင်း၊ သို့ အပြင်သို့ ထုတ်နိုင်မှု အခြေအနေများ မည်သို့ပင်ဖြစ်စေကာမူ အပလီကေးရှင်းအား လှုပ်ရှားမှုများအား စတင်ရန် ခွင့်ပြုပါ"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ဖန်သားပြင်နှင့် လိုက်ဖက်မှုကို သတ်မှတ်ရန်"</string>
     <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"အပလီကေးရှင်းအား တခြား အပလီကေးရှင်းများ ဖန်သားပြင် ပြသမှုအား ထိန်းချုပ်ခွင့်ပြုပါ။ အန္တရာယ်ရှိ အပလီကေးရှင်းများက တခြားအပလီကေးရှင်းများ ဒုက္ခပေးနိုင်ပါသည်"</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"app ဒီဘာဂင် ဖွင့်ပေးခြင်း"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"app ဒီဘာဂင် ဖွင့်ပေးခြင်း"</string>
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"အပလီကေးရှင်းအား တခြား အပလီကေးရှင်းအတွက် အမှားရှာဖွေပြင်ဆင်ခြင်း ခွင့်ပြုပါ။ အန္တရာယ်ရှိ အပလီကေးရှင်း ဒီခွင့်ပြုချက်အား သုံးပြီး တခြားအပလီကေးရှင်းအား ရပ်ပစ်နိုင်ပါသည်"</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"စနစ် ပြသမှုဆက်တင်များပြင်ရန်"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"အပလီကေးရှင်းအား လက်ရှိ အပြင်အဆင် ဥပမာ ဘာသာစကား၊ စာလုံးအကြီးအသေး များ ပြင်ခွင့် ပြုရန်"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ကားမောင်းနေစဥ်စနစ်အား ရရှိစေခြင်း"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"appအား ကား မုဒ် ဖွင့်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"appအား ကား မုဒ် ဖွင့်ခွင့် ပြုသည်။"</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"အခြား အပလီကေးရှင်းများအား ပိတ်ရန်"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"အပလီကေးရှင်းအား နောက်ကွယ်တွင် ဖွင့်ထားသော အခြားအပလီကေးရှင်းများရဲ့ လုပ်ဆောင်မှုများအား ရပ်ခွင့်ပေးပါ။ ဒီလိုလုပ်ခြင်းဖြင့် အခြား အပလီကေးရှင်းများ ရပ်တန့်သွားနိုင်ပါသည်"</string>
     <string name="permlab_forceStopPackages" msgid="2329627428832067700">"အခြား appများ ရပ်ပစ်ရန် အကြပ်ကိုင်ခြင်း"</string>
-    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"appအား အခြား appများ၏ အလုပ်ကို အတင်းအကြပ် ရပ်ပစ်ခွင့် ရှိသည်။"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"appအား အခြား appများ၏ အလုပ်ကို အတင်းအကြပ် ရပ်ပစ်ခွင့် ရှိသည်။"</string>
     <string name="permlab_forceBack" msgid="652935204072584616">"appကို ပိတ်သွားရန် အကြပ်ကိုင်ခြင်း"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"appအား အရှေ့ပိုင်းမှ မည်သည့် လှုပ်ရှားမှုကို မဆို ပိတ်ခွင့် နှင့် နောက်ကို ပို့ခွင့် ရှိသည်။ သာမန် appများ ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"appအား အရှေ့ပိုင်းမှ မည်သည့် လှုပ်ရှားမှုကို မဆို ပိတ်ခွင့် နှင့် နောက်ကို ပို့ခွင့် ရှိသည်။ သာမန် appများ ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_dump" msgid="1681799862438954752">"စနစ်၏စက်တွင်းအခြအေနေများထံ ပြန်ထုတ်ခြင်း"</string>
-    <string name="permdesc_dump" msgid="1778299088692290329">"appအား စနစ်၏ အတွင်းပိုင်း အခြေအနေကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများသည် ၎င်းတို့ အနေနှင့် ပုံမှန် ဘယ်တော့မှ မလိုအပ်သည့် ကိုယ်ရေး နှင့် လုံခြုံမှု အချက်အလက် အမျိုးမျိုးကို ရယူနိုင်ကြသည်။"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"appအား စနစ်၏ အတွင်းပိုင်း အခြေအနေကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများသည် ၎င်းတို့ အနေနှင့် ပုံမှန် ဘယ်တော့မှ မလိုအပ်သည့် ကိုယ်ရေး နှင့် လုံခြုံမှု အချက်အလက် အမျိုးမျိုးကို ရယူနိုင်ကြသည်။"</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ဖန်သားပြင်အကြောင်းအရာအားပြန်လည်ရယူရန်"</string>
-    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"appအား တက်ကြွ ဝင်ဒိုး၏ အကြောင်းအရာကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများက ဝင်ဒိုး၏ အကြောင်းအရာ တစ်ခုလုံးကို ရယူနိုင်ပြီး စကားဝှက်မှ လွဲပြီး ၎င်းထဲက စာသား တစ်ခုလုံးကို ဆန်းစစ်နိုင်သည်။"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"appအား တက်ကြွ ဝင်ဒိုး၏ အကြောင်းအရာကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများက ဝင်ဒိုး၏ အကြောင်းအရာ တစ်ခုလုံးကို ရယူနိုင်ပြီး စကားဝှက်မှ လွဲပြီး ၎င်းထဲက စာသား တစ်ခုလုံးကို ဆန်းစစ်နိုင်သည်။"</string>
     <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ယာယီ ရယူခွင့် ပြုရန်"</string>
     <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"အပလီကေးရှင်းအား စက်အား ခဏတာ အသုံးပြုခွင့်ပေးပါ။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ သုံးစွဲသူ မသိပဲ ရယူခြင်း လုပ်နိုင်ပါသည်"</string>
     <string name="permlab_retrieveWindowToken" msgid="7154762602367758602">"ဝင်ဒိုး တိုကင်ကို ရယူခြင်း"</string>
-    <string name="permdesc_retrieveWindowToken" msgid="668173747687795074">"အပလီကေးရှင်း တစ်ခုအား ဝင်ဒိုး တိုကင်ကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများက စနစ်လို အယောင်ဆောင်ကာ အပလီကေးရှင်း ဝင်ဒိုးနှင့် ခွင့်မပြုထားသည့် တုံ့ပြန်မှုကို ပြုလုပ်နိုင်သည်။"</string>
+    <string name="permdesc_retrieveWindowToken" msgid="668173747687795074">"အပလီကေးရှင်း တစ်ခုအား ဝင်ဒိုး တိုကင်ကို ရယူခွင့် ပြုသည်။ ကြံဖန် appများက စနစ်လို အယောင်ဆောင်ကာ အပလီကေးရှင်း ဝင်ဒိုးနှင့် ခွင့်မပြုထားသည့် တုံ့ပြန်မှုကို ပြုလုပ်နိုင်သည်။"</string>
     <string name="permlab_frameStats" msgid="7056374987314361639">"ဘောင် စာရင်းအင်းများကို ရယူခြင်း"</string>
-    <string name="permdesc_frameStats" msgid="4758001089491284919">"အပလီကေးရှင်း တစ်ခုအား မူဘောင် စာရင်းအင်းများကို စုစည်းစေနိုင်သည်။ ကြံဖန် appများက ဝင်ဒိုး၏ မူဘောင် စာရင်းအင်းများကို အခြား appများမှ စောင့်ကြည့်နိုင်သည်။"</string>
+    <string name="permdesc_frameStats" msgid="4758001089491284919">"အပလီကေးရှင်း တစ်ခုအား မူဘောင် စာရင်းအင်းများကို စုစည်းစေနိုင်သည်။ ကြံဖန် appများက ဝင်ဒိုး၏ မူဘောင် စာရင်းအင်းများကို အခြား appများမှ စောင့်ကြည့်နိုင်သည်။"</string>
     <string name="permlab_filter_events" msgid="8675535648807427389">"အဖြစ်အပျက်များအား စစ်ထုတ်ခြင်း"</string>
     <string name="permdesc_filter_events" msgid="8006236315888347680">"အပလီကေးရှင်းအား သုံးစွဲသူ လုပ်ဆောင်မှုကို မပြုလုပ်ခင် စစ်ဆေးပေးသော input filter မှတ်ပုံတင်ခွင့်ပြုရန်၊ အန္တရယယ် ရှိသော အပလီကေးရှင်းများမှ သုံးစွဲသူ မသိပဲ စနစ်ပုံရိပ်ပြမှုအား ထိန်းချုပ်နိုင်ပါသည်"</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"တစိတ်တပိုင်းအားပိတ်ချရန်"</string>
-    <string name="permdesc_shutdown" msgid="7046500838746291775">"လုပ်ဆောင်မှုမန်နေဂျာကို ပိတ်ထားသည့်အခြေအနေတွင်ထားသည်။ အပြီးပိတ်ခြင်းအား မပြုလုပ်ပါ။"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"လုပ်ဆောင်မှုမန်နေဂျာကို ပိတ်ထားသည့်အခြေအနေတွင်ထားသည်။ အပြီးပိတ်ခြင်းအား မပြုလုပ်ပါ။"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"အပ်ပလီကေးရှင်းဖလှယ်ခြင်းမှ မဖြစ်စေရန်"</string>
-    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"အသုံးပြုသူကို အခြား appသို့ ခလုတ် ပြောင်းမရအောင် ဟန့်တားသည်။"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"အသုံးပြုသူကို အခြား appသို့ ခလုတ် ပြောင်းမရအောင် ဟန့်တားသည်။"</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"အပလီကေးရှင်း အချက်အလက်များ ယူခြင်း"</string>
     <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ကိုင်ဆောင်ထားသူအား လက်ရှိ အပလီကေးရှင်းမှ လျို့ဝှက် အချက်အလက်များအား ထုတ်ယူကြည့်ခွင့်ပြုခြင်း"</string>
-    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"app အားလုံး ဖွင့်တင်မှုကို စောင့်ကြည့်ခြင်း နှင့် ထိန်းချုပ်ခြင်း"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"appအား စနစ်မှ လှုပ်ရှားမှုများကို ဖွင့်လှစ်စတင်ပုံကို စောင့်ကြည့်လျက် ထိန်းချုပ်ခွင့် ပြုသည်။ ကြံဖန် appများက စနစ်ကို လုံးဝ ဖျက်ဆီးပစ်နိုင်ကြသည်။ ယင်း ခွင့်ပြုချက်မှာ တိုးတက်အောင် ပြုစုရာမှာသာ လိုအပ်ပြီး၊ ပုံမှန် အသုံးပြုမှု အတွက် လုံးဝ မဟုတ်ပါ။"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"app အားလုံး ဖွင့်တင်မှုကို စောင့်ကြည့်ခြင်း နှင့် ထိန်းချုပ်ခြင်း"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"appအား စနစ်မှ လှုပ်ရှားမှုများကို ဖွင့်လှစ်စတင်ပုံကို စောင့်ကြည့်လျက် ထိန်းချုပ်ခွင့် ပြုသည်။ ကြံဖန် appများက စနစ်ကို လုံးဝ ဖျက်ဆီးပစ်နိုင်ကြသည်။ ယင်း ခွင့်ပြုချက်မှာ တိုးတက်အောင် ပြုစုရာမှာသာ လိုအပ်ပြီး၊ ပုံမှန် အသုံးပြုမှု အတွက် လုံးဝ မဟုတ်ပါ။"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"package ပယ်ဖျက်မှု ထုတ်လွှင့်မှုအား ပေးပို့ပါ"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"appအား app အထုပ် တစ်ခုကို ဖယ်ရှားပစ်လိုက်ကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို  အသုံးပြုပြီး အလုပ်လုပ်နေသည့် မည့်သည့် appကို မဆို သတ်ပစ်နိုင်သည်။"</string>
-    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-အားပို့ပြီး ထုတ်လွင့်မှုအားရယူခြင်း"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"appအား SMS ရရှိထားကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး ဝင်လာကြသည့် SMS စာများကို အတုလုပ်နိုင်သည်။"</string>
-    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-အားပို့ပြီး ထုတ်လွင့်မှုအားရယူခြင်း"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"appအား WAP PUSH စာ ရရှိထားကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး ရရှိခဲ့သည့်MMS စာများကို လုပ်ကြံနိုင်သလို၊ မည်သည့် ဝက်ဘ် စာမျက်နှာ၏ အကြောင်းအရာကို မဆို လုပ်ကြံချက်များဖြင့် တိတ်တိတ်ပုန်း အစားထိုးနိုင်သည်။"</string>
-    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"အလုပ်လုပ်နေသောလုပ်ငန်းစဥ်နှုန်းအား ကန့်သတ်ခြင်း"</string>
-    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"appအား အလုပ်လုပ်ကြမည့် လုပ်ငန်းစဉ်များ၏ အများဆုံး အရေအတွက်ကို ထိန်းချုပ်ခွင့် ပြုနိုင်သည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"appအား app အထုပ် တစ်ခုကို ဖယ်ရှားပစ်လိုက်ကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို  အသုံးပြုပြီး အလုပ်လုပ်နေသည့် မည့်သည့် appကို မဆို သတ်ပစ်နိုင်သည်။"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-အားပို့ပြီး ထုတ်လွင့်မှုအားရယူခြင်း"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"appအား SMS ရရှိထားကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး ဝင်လာကြသည့် SMS စာများကို အတုလုပ်နိုင်သည်။"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-အားပို့ပြီး ထုတ်လွင့်မှုအားရယူခြင်း"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"appအား WAP PUSH စာ ရရှိထားကြောင်း အကြောင်းကြားစာကို ထုတ်လွင့်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး ရရှိခဲ့သည့်MMS စာများကို လုပ်ကြံနိုင်သလို၊ မည်သည့် ဝက်ဘ် စာမျက်နှာ၏ အကြောင်းအရာကို မဆို လုပ်ကြံချက်များဖြင့် တိတ်တိတ်ပုန်း အစားထိုးနိုင်သည်။"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"အလုပ်လုပ်နေသောလုပ်ငန်းစဥ်နှုန်းအား ကန့်သတ်ခြင်း"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"appအား အလုပ်လုပ်ကြမည့် လုပ်ငန်းစဉ်များ၏ အများဆုံး အရေအတွက်ကို ထိန်းချုပ်ခွင့် ပြုနိုင်သည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"နောက်ခံ အပလီကေးရှင်းအား မဖြစ်မနေပိတ်ရန်"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"appအား လှုပ်ရှားမှုများ နောက်ခံသို့ သွားကြသည့်နှင့် ပြီးဆုံးခြင်း ရှိမရှိကို အမြဲတမ်း ထိန်းချုပ်ခွင့် ရှိသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်ပါ။"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"appအား လှုပ်ရှားမှုများ နောက်ခံသို့ သွားကြသည့်နှင့် ပြီးဆုံးခြင်း ရှိမရှိကို အမြဲတမ်း ထိန်းချုပ်ခွင့် ရှိသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်ပါ။"</string>
     <string name="permlab_batteryStats" msgid="2789610673514103364">"ဘတ်ထရီ အခြေအနေအား ဖတ်ရန်"</string>
     <string name="permdesc_batteryStats" msgid="5897346582882915114">"အပလီကေးရှင်းအား အနိမ့်ပိုင်း စက် အချက်အလက် ဘက်ထရီ အခြေအနေကို ကြည့်ခွင့်ပြုပါ။ အပလီကေးရှင်းမှ သင် အသုံးပြုသော အပလီကေးရှင်းများ၏ အသေးစိတ် သတင်းအချက်အလက်များကို ရှာဖွေရန် ခွင့်ပြုပါ။"</string>
     <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ဘက်ထရီ အချက်အလက်အား ပြင်ရန်"</string>
@@ -386,28 +386,28 @@
     <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"အပလီကေးရှင်းကို အပလီကေးရှင်း အသုံးပြုမှု အချက်အလက် စာရင်းများအား ယူသုံးခွင့် ပြုခြင်း။ ပုံမှန် အပလီကေးရှင်းများအတွက် မဟုတ်ပါ"</string>
     <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"အပလီကေးရှင်း အသုံးပြုမှုအား ပြင်ဆင်ခြင်း"</string>
     <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"အပလီကေးရှင်းကို အပလီကေးရှင်း အသုံးပြုမှု အချက်အလက် စာရင်းများအား ပြောင်းလဲခွင့် ပြုခြင်း။ ပုံမှန် အပလီကေးရှင်းများအတွက် မဟုတ်ပါ"</string>
-    <string name="permlab_backup" msgid="470013022865453920">"စနစ်အရန်သိမ်းဆည်းမှုနှင့် ပြန်လည်ရယူရန် ထိန်းချုပ်ခြင်း"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"appအား စနစ်၏ ဘက်အာပ် နှင့် ပြန်လည် ဖေါ်ထုတ်ရေး ယန္တရားကို ထိန်းချုပ်ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
-    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"အပြည့်အဝအရန်သိမ်းဆည်းရန် သို့မဟုတ် ပြန်လည်ရယူခြင်းအောက်ပရေးရှင်းအား အတည်ပြုရန်"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"appအား ဘက်အာပ် အတည်ပြုရေး UI အပြည့်အဝကို ဖွင့်တင်ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
-    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ခွင့်မပြုထားသောဝင်ဒိုးမျာကို ဖော်ပြခြင်း"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"စနစ်အရန်သိမ်းဆည်းမှုနှင့် ပြန်လည်ရယူရန် ထိန်းချုပ်ခြင်း"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"appအား စနစ်၏ ဘက်အာပ် နှင့် ပြန်လည် ဖေါ်ထုတ်ရေး ယန္တရားကို ထိန်းချုပ်ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"အပြည့်အဝအရန်သိမ်းဆည်းရန် သို့မဟုတ် ပြန်လည်ရယူခြင်းအောက်ပရေးရှင်းအား အတည်ပြုရန်"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"appအား ဘက်အာပ် အတည်ပြုရေး UI အပြည့်အဝကို ဖွင့်တင်ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ခွင့်မပြုထားသောဝင်ဒိုးမျာကို ဖော်ပြခြင်း"</string>
     <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"အပလီကေးရှင်း အတွင်းပိုင်းစနစ်သာ သုံးရန်သင့်သော ဝင်းဒိုးများ တည်ဆောက်ခွင့် ပြုပါ။ ပုံမှန် အပလီကေးရှင်းများအတွက် မရည်ရွယ်ပါ"</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"တခြား အပလီကေးရှင်းပေါ်တွင် ထပ်ဆွဲရန်"</string>
     <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"အပလီကေးရှင်းအား အခြားအပလီကေးရှင်းများ သို့ တခြား အသုံးပြုသူ မြင်ရသော နေရာများပေါ်တွင် ထပ်၍ ရေးဆွဲခွင့် ပေးသည်။ ဒီခွင့်ပြုမှုဟာ သင် အပလီကေးရှင်းများနဲ့ အသုံးပြုရန် စီစဉ်ထားမှု သို့ သင် မြင်ရသောမြင်ကွင်းအား ပြောင်းလဲမှု ဖြစ်စေနိုင်သည်"</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"တကမ္ဘာလုံးဆိုင်ရာ လှုပ်ရှားသက်ဝင်နှုန်းမွမ်းမံခြင်း"</string>
     <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"အပလီကေးရှင်းအား စက်တစ်ခုလုံးနှင့်ဆိုင်သော သရုပ်ပြမှု အနှေး အမြန် နှုန်း အား အချိန်မရွေး ပြောင်းခွင့်ပြုပါ"</string>
     <string name="permlab_manageAppTokens" msgid="1286505717050121370">"app တိုကင်များကို စီမံကွပ်ကဲခြင်း"</string>
-    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"appအား၊ ၎င်းတို့၏ ပုံမှန် Z-အော်ဒါပေးမှုကို ကျော်လွှားပြီး၊  ၎င်းတို့၏ ကိုယ်ပိုင် တိုကင်များကို ဖန်တီးရန် နှင့် စီမံကွပ်ကဲခွင့်ကို ပြုသည်။ သာမန် appများ အတွက ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"appအား၊ ၎င်းတို့၏ ပုံမှန် Z-အော်ဒါပေးမှုကို ကျော်လွှားပြီး၊  ၎င်းတို့၏ ကိုယ်ပိုင် တိုကင်များကို ဖန်တီးရန် နှင့် စီမံကွပ်ကဲခွင့်ကို ပြုသည်။ သာမန် appများ အတွက ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_freezeScreen" msgid="4708181184441880175">"ဖန်သားပြင်အား ရပ်တန့်စေခြင်း"</string>
     <string name="permdesc_freezeScreen" msgid="8558923789222670064">"အပလီကေးရှင်းအား ဖန်သားပြည့် ပြသမှုအတွက် ပြောင်းလဲစဉ် ဖန်သားပြင်အား ခဏရပ်ခွင့်ပြုရန်"</string>
-    <string name="permlab_injectEvents" msgid="1378746584023586600">"ခလုတ်များနှင့် ထိန်းချုပ်သည့်ခလုတ်များကို နှိပ်ခြင်း"</string>
-    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"appအား ၎င်းကိုယ်နှိုက်၏ ထည့်သွင်းမှုများ (ခလုတ် နှိပ်မှုများ၊ စသဖြင့်)ကို ထည့်ပေးခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး တက်ဘလက်၏ နေရာကို ရယူနိုင်သည်။"</string>
-    <string name="permdesc_injectEvents" product="tv" msgid="4681361983270791611">"အခြား app များသို့ ၎င်းကိုယ်တိုင်သွင်းယူထားသော (key presses၊ အစရှိသည့်) ဖြစ်ရပ်များအား ပေးပို့ရန် app အား ခွင့်ပြုပါ။ ဤအရာကို အသုံးပြုရန်အတွက် အန္တရာယ်ရှိသော app များက တီဗွီအား ထိန်းချုပ်နိုင်သည်။"</string>
-    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"appအား ၎င်းကိုယ်နှိုက်၏ ထည့်သွင်းမှုများ (ခလုတ် နှိပ်မှုများ၊ စသဖြင့်)ကို ထည့်ပေးခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး ဖုန်း၏ နေရာကို ရယူနိုင်သည်။"</string>
-    <string name="permlab_readInputState" msgid="469428900041249234">"သင်မည်သည်ကိုရိုက်သွင်းသည်နှင့် လှုပ်ရှားမှုများကို မှတ်တမ်းတင်ခြင်း"</string>
-    <string name="permdesc_readInputState" msgid="8387754901688728043">"appအား သင် နှိပ်သည့် ခလုတ်များကို၊ သင်က အခြား app တစ်ခုနှင့် (စကားဝှက် ရိုက်ထည့်မှုလို) အပြန်အလှန် တုံ့ပြန်နေချိန်မှာတောင်၊ စောင့်ကြည့်ခွင့် ပြုသည်။"</string>
-    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ထည့်သွင်းရန်နည်းလမ်းအား ဆက်ရန်"</string>
-    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"စွဲကိုင်ထားသူအား ရိုက်ထည့်ရေး နည်းလမ်း၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ခလုတ်များနှင့် ထိန်းချုပ်သည့်ခလုတ်များကို နှိပ်ခြင်း"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"appအား ၎င်းကိုယ်နှိုက်၏ ထည့်သွင်းမှုများ (ခလုတ် နှိပ်မှုများ၊ စသဖြင့်)ကို ထည့်ပေးခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး တက်ဘလက်၏ နေရာကို ရယူနိုင်သည်။"</string>
+    <string name="permdesc_injectEvents" product="tv" msgid="4681361983270791611">"အခြား app များသို့ ၎င်းကိုယ်တိုင်သွင်းယူထားသော (key presses၊ အစရှိသည့်) ဖြစ်ရပ်များအား ပေးပို့ရန် app အား ခွင့်ပြုပါ။ ဤအရာကို အသုံးပြုရန်အတွက် အန္တရာယ်ရှိသော app များက တီဗွီအား ထိန်းချုပ်နိုင်သည်။"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"appအား ၎င်းကိုယ်နှိုက်၏ ထည့်သွင်းမှုများ (ခလုတ် နှိပ်မှုများ၊ စသဖြင့်)ကို ထည့်ပေးခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး ဖုန်း၏ နေရာကို ရယူနိုင်သည်။"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"သင်မည်သည်ကိုရိုက်သွင်းသည်နှင့် လှုပ်ရှားမှုများကို မှတ်တမ်းတင်ခြင်း"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"appအား သင် နှိပ်သည့် ခလုတ်များကို၊ သင်က အခြား app တစ်ခုနှင့် (စကားဝှက် ရိုက်ထည့်မှုလို) အပြန်အလှန် တုံ့ပြန်နေချိန်မှာတောင်၊ စောင့်ကြည့်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ထည့်သွင်းရန်နည်းလမ်းအား ဆက်ရန်"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"စွဲကိုင်ထားသူအား ရိုက်ထည့်ရေး နည်းလမ်း၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"အသုံးပြုမှု ပေးနိုင်သော ဆားဗစ်တစ်ခုနှင့် ပူးပေါင်းမှု ပြုရန်"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ဖုန်းကိုင်ထားသူနဲ့ ရယူခွင့်ပြုသော ဆားဗစ်မှ ထိပ်ပိုင်းအင်တာဖေ့စ် ကို ပူပေါင်းခွင့်ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ။"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"စာထုတ်မှု ဆားဗစ်နှင့် ပူးပေါင်းခြင်း"</string>
@@ -417,100 +417,100 @@
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC ဆားဗစ်နှင့်ပူးပေါင်းခြင်း"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ဖုန်းကိုင်ထားသူနှင့် NFC ထုတ်လွှတ်နေတဲ့ အပလီကေးရှင်း ကို ပူးပေါင်းခွင့် ပေးခြင်း၊. ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"စာတိုပို့ခြင်းဆားဗစ်နှင့် ပူးပေါင်းခြင်း"</string>
-    <string name="permdesc_bindTextService" msgid="8151968910973998670">"စွဲကိုင်ထားသူအား စာသား ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"စွဲကိုင်ထားသူအား စာသား ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPNဆားဗစ်နှင့် ပူးပေါင်းခြင်း"</string>
-    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"စွဲကိုင်ထားသူအား Vpn ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
-    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"နောက်ခံနှင့် ပူးပေါင်းခြင်း"</string>
-    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"စွဲကိုင်ထားသူအား နောက်ခံ ပုံ၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"စွဲကိုင်ထားသူအား Vpn ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"နောက်ခံနှင့် ပူးပေါင်းခြင်း"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"စွဲကိုင်ထားသူအား နောက်ခံ ပုံ၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_bindVoiceInteraction" msgid="5334852580713715068">"အသံ တုံ့ပြန်လုပ်ပေးသူ တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
-    <string name="permdesc_bindVoiceInteraction" msgid="2345721766501778101">"စွဲကိုင်ထားသူအား အသံဖြင့် တုံ့ပြန်ရေး ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_bindVoiceInteraction" msgid="2345721766501778101">"စွဲကိုင်ထားသူအား အသံဖြင့် တုံ့ပြန်ရေး ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_manageVoiceKeyphrases" msgid="1252285102392793548">"အသံ သော့ချက် စကားရပ်များကို စီမံကွပ်ကဲရန်"</string>
-    <string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"စွဲကိုင်ထားသူအား စကားလုံးတို ရှာကြံရေး အတွက် သော့ချက် စကားရပ်များကို စီမံခွင့်ပြုသည်။သာမန် appများ အတွက် ဘယ်တော့မှ လိုအပ်မည် မဟုတ်။"</string>
+    <string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"စွဲကိုင်ထားသူအား စကားလုံးတို ရှာကြံရေး အတွက် သော့ချက် စကားရပ်များကို စီမံခွင့်ပြုသည်။သာမန် appများ အတွက် ဘယ်တော့မှ လိုအပ်မည် မဟုတ်။"</string>
     <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ထိန်းချုပ်ပြသခြင်း နဲ့ ပူးပေါင်းရန်"</string>
     <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ဖုန်းကိုင်ထားသူနဲ့ ထိန်းချုပ်ပြသမှုမှ ထိပ်ပိုင်းအင်တာဖေ့စ် ကို ပူးပေါင်းခွင့်ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
-    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ဝဒ်ဂျက်ဝန်ဆောင်မှုနှင့် ပူးပေါင်းရန်"</string>
-    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"စွဲကိုင်ထားသူအားဝီဂျက် ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
-    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"စက်ပစ္စည်း ထိန်းချုပ်ခြင်းနှင့် တုံ့ပြန်မှု"</string>
-    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"စွဲကိုင်ထားသူအား ကိရိယာ စီမံအုပ်ချုပ်သူထံသို့ ရည်ရွယ်ချက်များကို ပို့ခွင့် ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
-    <string name="permlab_bindTvInput" msgid="5601264742478168987">"တီဗီ ထည့်သွင်းမှု တစ်ခုဆီသို့ ချိတ်တွဲပေးခြင်း"</string>
-    <string name="permdesc_bindTvInput" msgid="2371008331852001924">"စွဲကိုင်ထားသူအား တီဗီ ထည့်သွင်းမှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ဝဒ်ဂျက်ဝန်ဆောင်မှုနှင့် ပူးပေါင်းရန်"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"စွဲကိုင်ထားသူအားဝီဂျက် ဝန်ဆောင်မှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"စက်ပစ္စည်း ထိန်းချုပ်ခြင်းနှင့် တုံ့ပြန်မှု"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"စွဲကိုင်ထားသူအား ကိရိယာ စီမံအုပ်ချုပ်သူထံသို့ ရည်ရွယ်ချက်များကို ပို့ခွင့် ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_bindTvInput" msgid="5601264742478168987">"တီဗီ ထည့်သွင်းမှု တစ်ခုဆီသို့ ချိတ်တွဲပေးခြင်း"</string>
+    <string name="permdesc_bindTvInput" msgid="2371008331852001924">"စွဲကိုင်ထားသူအား တီဗီ ထည့်သွင်းမှု၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_modifyParentalControls" msgid="4611318225997592242">"မိဘ ထိန်းချုပ်မှုများကို မွမ်းမံရန်"</string>
-    <string name="permdesc_modifyParentalControls" msgid="7438482894162282039">"ပိုင်ရှင်အား စနစ်၏ မိဘများ ထိန်းချုပ်ရေး ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ ပုံမှန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_modifyParentalControls" msgid="7438482894162282039">"ပိုင်ရှင်အား စနစ်၏ မိဘများ ထိန်းချုပ်ရေး ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ ပုံမှန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"စက်အက်မင်တစ်ယောက် ကို ထည့်ခြင်း သို့ ထုတ်ခြင်း"</string>
     <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"အသုံးပြုသူအား အက်ဒ်မင်များအား ထည့်ခြင်း ထုတ်ခြင်း ပြုလုပ်ခွင့် ပေးခြင်း။ . ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"စကရင်အနေအထားအားပြောင်းခြင်း"</string>
-    <string name="permdesc_setOrientation" msgid="3046126619316671476">"appအား မျက်နှာပြင် လည်မှုကို အချိန်မရွေး ရပ်ပစ်ခွင့် ပြုသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"appအား မျက်နှာပြင် လည်မှုကို အချိန်မရွေး ရပ်ပစ်ခွင့် ပြုသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"မြားအမြန်နှုန်းအား ပြောင်းခြင်း"</string>
-    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"appအား မောက်စ်ကို သို့မဟုတ် ထရက်ပဲဒ် ညွှန်တံ၏ နှုန်းကို အချိန်မရွေး ပြောင်းခွင့် ရှိသည်။သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"appအား မောက်စ်ကို သို့မဟုတ် ထရက်ပဲဒ် ညွှန်တံ၏ နှုန်းကို အချိန်မရွေး ပြောင်းခွင့် ရှိသည်။သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"လက်ကွက် အပြင်အဆင်ပြောင်းရန်"</string>
     <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"အပလီကေးရှင်းအား လက်ကွက်အပြင်အဆင်အား ပြောင်းခွင့်ပြုပါ။ ပုံမှန် အပလီကေးရှင်းများတွင် မလိုအပ်ပါ။"</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"appများသို့ Linux အချက်ပြမှု ပို့ခြင်း"</string>
-    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"appအား ပို့နေသော အချက်ပြမှုကို ရှိနေကြသည့် လုပ်ငန်းစဉ် အားလုံးထံသို့ ပို့ရေးကို တောင်းဆိုခွင့် ပေးသည်။"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"appအား ပို့နေသော အချက်ပြမှုကို ရှိနေကြသည့် လုပ်ငန်းစဉ် အားလုံးထံသို့ ပို့ရေးကို တောင်းဆိုခွင့် ပေးသည်။"</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"appကို အမြဲတမ်း အလုပ်လုပ်စေခြင်း"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"အပလီကေးရှင်းအား မှတ်ဉာဏ်ထဲတွင် ရေရှည်သိမ်းဆည်ထားရန် ခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် တခြားအပလီကေးရှင်းအများအတွက် မှတ်ဉာဏ်ရရှိမှု နည်းသွားနိုင်ပြီး တက်ဘလက်လည်း နှေးသွားနိုင်ပါသည်။"</string>
-    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"မှတ်ဉာဏ်တွင် ၎င်း၏အစိတ်အပိုင်းများကိုယ်တိုင် တည်မြဲနေစေရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် တီဗွီကို နှေးစေသော အခြား app များ၏ မှတ်ဉာဏ်ကို ကန့်သတ်ထားနိုင်သည်။"</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"မှတ်ဉာဏ်တွင် ၎င်း၏အစိတ်အပိုင်းများကိုယ်တိုင် တည်မြဲနေစေရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် တီဗွီကို နှေးစေသော အခြား app များ၏ မှတ်ဉာဏ်ကို ကန့်သတ်ထားနိုင်သည်။"</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"အပလီကေးရှင်းအား မှတ်ဉာဏ်ထဲတွင် ရေရှည်သိမ်းဆည်ထားရန် ခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် တခြားအပလီကေးရှင်းအများအတွက် မှတ်ဉာဏ်ရရှိမှု နည်းသွားနိုင်ပြီး ဖုန်းလည်း နှေးသွားနိုင်ပါသည်။"</string>
     <string name="permlab_deletePackages" msgid="184385129537705938">"appများကို ဖျက်ရန်"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"appအား အန်ဒရွိုက် အထုပ်များကို ဖျက်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် appများကို ဖျက်ပစ်နိုင်သည်။"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"appအား အန်ဒရွိုက် အထုပ်များကို ဖျက်ခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် appများကို ဖျက်ပစ်နိုင်သည်။"</string>
     <string name="permlab_clearAppUserData" msgid="274109191845842756">"အခြား appများ၏ ဒေတာကို ဖျက်ရန်"</string>
-    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"appအား အသုံးပြုသူ ဒေတာကို ရှင်းပစ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"appအား အသုံးပြုသူ ဒေတာကို ရှင်းပစ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"အခြား appများ၏ ကက်ရှများကို ဖျက်ရန်"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"appအား ကက်ရှ ဖိုင်များကို ဖျက်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"appအား ကက်ရှ ဖိုင်များကို ဖျက်ခွင့် ပြုသည်။"</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"app သိုလ​ှောင်မှု နေရာကို တိုင်းထွာခြင်း"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"appအား ၎င်း၏ ကုဒ်၊ ဒေတာ၊ နှင့် ကက်ရှ ဆိုက်များကို ရယူခွင့် ပြုသည်။"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"appအား ၎င်း၏ ကုဒ်၊ ဒေတာ၊ နှင့် ကက်ရှ ဆိုက်များကို ရယူခွင့် ပြုသည်။"</string>
     <string name="permlab_installPackages" msgid="2199128482820306924">"appများကို တိုက်ရိုက် တပ်ဆင်ခြင်း"</string>
-    <string name="permdesc_installPackages" msgid="5628530972548071284">"appအား အန်ဒရွိုက် အထုပ် အသစ် သို့မဟုတ် မွမ်းမံပြီးကို တပ်ဆင်ခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး ထင်ရာလုပ်နိုင်သော ကြီးမားသည့် ခွင့်ပြုချက်များ ရှိမည့် appများကို ထည့်ပေးနိုင်ကြသည်။"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"appအား အန်ဒရွိုက် အထုပ် အသစ် သို့မဟုတ် မွမ်းမံပြီးကို တပ်ဆင်ခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးပြုပြီး ထင်ရာလုပ်နိုင်သော ကြီးမားသည့် ခွင့်ပြုချက်များ ရှိမည့် appများကို ထည့်ပေးနိုင်ကြသည်။"</string>
     <string name="permlab_clearAppCache" msgid="7487279391723526815">"app ကက်ရှ ဒေတာ အားလုံးကို ဖျက်ပစ်ရန်"</string>
     <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"အပလီကေးရှင်းမှာ တခြား အပလီကေးရှင်းများမှ ဒေတာများအား ယာယီ သိုလှောင်မှုနေရာမှ ဖျက်ပစ်ပြီး နေရာလွတ် လုပ်ခွင့်ပြုပါ။ ဒီလိုလုပ်ခြင်းဖြင့် တခြား အပလီကေးရှင်းများ စတင်ရာတွင် နှေးကွေးမှု ဖြစ်စေနိုင်ပါသည်။"</string>
-    <string name="permdesc_clearAppCache" product="tv" msgid="244647416303997022">"အခြား အပလီကေးရှင်းများ၏ ကာရှ်လမ်းညွှန်များရှိ ဖိုင်များအား ဖျက်ခြင်းဖြင့် တီဗွီ၏ သိုလှောင်ရုံအား နေရာလွတ်ရနိုင်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် အခြားအပလီကေးရှင်းများသည် ၎င်းတို့၏ဒေတာများကို ပြန်လည်ရယူရန် စတင်သည့်အခါ ပိုမိုနှေးကွေးနေမည်ဖြစ်၏။"</string>
+    <string name="permdesc_clearAppCache" product="tv" msgid="244647416303997022">"အခြား အပလီကေးရှင်းများ၏ ကာရှ်လမ်းညွှန်များရှိ ဖိုင်များအား ဖျက်ခြင်းဖြင့် တီဗွီ၏ သိုလှောင်ရုံအား နေရာလွတ်ရနိုင်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် အခြားအပလီကေးရှင်းများသည် ၎င်းတို့၏ဒေတာများကို ပြန်လည်ရယူရန် စတင်သည့်အခါ ပိုမိုနှေးကွေးနေမည်ဖြစ်၏။"</string>
     <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"အပလီကေးရှင်းမှာ တခြား အပလီကေးရှင်းများမှ ဒေတာများအား ယာယီ သိုလှောင်မှုနေရာမှ ဖျက်ပစ်ပြီး နေရာလွတ် လုပ်ခွင့်ပြုပါ။ ဒီလိုလုပ်ခြင်းဖြင့် တခြား အပလီကေးရှင်းများ စတင်ရာတွင် နှေးကွေးမှု ဖြစ်စေနိုင်ပါသည်။"</string>
     <string name="permlab_movePackage" msgid="3289890271645921411">"app အရင်းအမြစ်များကို ဖယ်ရှားခြင်း"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်းကို app၏ အရင်းအမြစ်များကို အတွင်းမှ အပြင်သို့ ရွှေ့ပြောင်းခြင်း နှင့် ပြောင်းပြန်လုပ်ခြင်းကို ခွင့်ပြုသည်။"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်းကို app၏ အရင်းအမြစ်များကို အတွင်းမှ အပြင်သို့ ရွှေ့ပြောင်းခြင်း နှင့် ပြောင်းပြန်လုပ်ခြင်းကို ခွင့်ပြုသည်။"</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"တုံ့ပြန်မှုလွယ်သောစာ​ရင်းဒေတာအားဖတ်ခြင်း"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"appအား စနစ်၏ လော့ဂ် ဖိုင် အမျိုးမျိုးတို့ကို ဖတ်ကြားခွင့် ပြုသည်။ သို့ဖြစ်၍ ၎င်းသည် သင်က တက်ဘလက်နှင့် ဘာတွေ လုပ်ကိုင်နေကြောင်း အထွေထွေ အချက်အလက်များကို၊ ဖြစ်နိုင်သည်မှာ ကိုယ်ရေး သို့မဟုတ် ပုဂ္ဂိုလ်ရေး အချက်အလက်များ အပါအဝင် တို့ကိုပါ၊ ရှာတွေ့သိလာနိုင်သည်။"</string>
-    <string name="permdesc_readLogs" product="tv" msgid="9023899974809538988">"စနစ်၏ လော့ဂ်ဖိုင်မျိုးစုံ ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် ကိုယ်ရေးကိုယ်တာ သို့မဟုတ် သီးသန့် အချက်အလက်များ အပါအဝင်၊ တီဗွီတွင် သင်လုပ်ဆောင်နေသော အထွေထွေ အချက်အလက်များကို ရှာဖွေတွေ့ရှိရန် ၎င်းအား ခွင့်ပြုခြင်းဖြစ်သည်။"</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"appအား စနစ်၏ လော့ဂ် ဖိုင် အမျိုးမျိုးတို့ကို ဖတ်ကြားခွင့် ပြုသည်။ သို့ဖြစ်၍ ၎င်းသည် သင်က ဖုန်းနှင့် ဘာတွေ လုပ်ကိုင်နေကြောင်း အထွေထွေ အချက်အလက်များကို၊ ဖြစ်နိုင်သည်မှာ ကိုယ်ရေး သို့မဟုတ် ပုဂ္ဂိုလ်ရေး အချက်အလက်များ အပါအဝင် တို့ကိုပါ၊ ရှာတွေ့သိလာနိုင်သည်။"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"appအား စနစ်၏ လော့ဂ် ဖိုင် အမျိုးမျိုးတို့ကို ဖတ်ကြားခွင့် ပြုသည်။ သို့ဖြစ်၍ ၎င်းသည် သင်က တက်ဘလက်နှင့် ဘာတွေ လုပ်ကိုင်နေကြောင်း အထွေထွေ အချက်အလက်များကို၊ ဖြစ်နိုင်သည်မှာ ကိုယ်ရေး သို့မဟုတ် ပုဂ္ဂိုလ်ရေး အချက်အလက်များ အပါအဝင် တို့ကိုပါ၊ ရှာတွေ့သိလာနိုင်သည်။"</string>
+    <string name="permdesc_readLogs" product="tv" msgid="9023899974809538988">"စနစ်၏ လော့ဂ်ဖိုင်မျိုးစုံ ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် ကိုယ်ရေးကိုယ်တာ သို့မဟုတ် သီးသန့် အချက်အလက်များ အပါအဝင်၊ တီဗွီတွင် သင်လုပ်ဆောင်နေသော အထွေထွေ အချက်အလက်များကို ရှာဖွေတွေ့ရှိရန် ၎င်းအား ခွင့်ပြုခြင်းဖြစ်သည်။"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"appအား စနစ်၏ လော့ဂ် ဖိုင် အမျိုးမျိုးတို့ကို ဖတ်ကြားခွင့် ပြုသည်။ သို့ဖြစ်၍ ၎င်းသည် သင်က ဖုန်းနှင့် ဘာတွေ လုပ်ကိုင်နေကြောင်း အထွေထွေ အချက်အလက်များကို၊ ဖြစ်နိုင်သည်မှာ ကိုယ်ရေး သို့မဟုတ် ပုဂ္ဂိုလ်ရေး အချက်အလက်များ အပါအဝင် တို့ကိုပါ၊ ရှာတွေ့သိလာနိုင်သည်။"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"မည်သည့် မီဒီယာ ဒီကုဒ်ဒါမဆို ပြသရာတွင် သုံးရန်"</string>
     <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_bindJobService" msgid="3637568367978271086">"အပလီကေးရှင်း၏ စီစဉ်ထားသည့် နောက်ခံ အလုပ်ကို လုပ်ကိုင်ရန်"</string>
+    <string name="permlab_bindJobService" msgid="3637568367978271086">"အပလီကေးရှင်း၏ စီစဉ်ထားသည့် နောက်ခံ အလုပ်ကို လုပ်ကိုင်ရန်"</string>
     <string name="permdesc_bindJobService" msgid="3473288460524119838">"ဒီခွင့်ပြုချက်က တောင်းဆိုလာလျှင် အန်ဒရွိုက် စနစ်အား အပလီကေးရှင်းကို နောက်ခံမှာ အလုပ် လုပ်ကိုင်စေပါသည်။"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagမှပိုင်ဆိုင်သော ရင်းနှီးမှုများကို ဖတ်/ရေးခြင်း"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"appအား diag အုပ်စု ပိုင်ဆိုင်သည့် မည်သည့် အရင်းအမြစ်ကို မဆို ရေးခြင်း နှင့် ဖတ်ခြင်းကို ခွင့်ပြုသည်၊ ဥပမာ၊ /dev ထဲက ဖိုင်များ။ ၎င်းက စနစ်၏ တည်ငြိမ်မှု နှင့် လုံခြုံမှုကို ထိပါးနိုင်သည့် အလားအလာ ရှိသည်။ ထုတ်လုပ်သူ သို့မဟုတ် အော်ပရေတာက ဟာ့ဒ်ဝဲ ဆိုင်ရာ ပြဿနာ ရှာဖွေ စူးစမ်းမှု အတွက်သာ ၎င်းကို အသုံးပြုရမည်။"</string>
-    <string name="permlab_changeComponentState" msgid="6335576775711095931">"app အစိတ်အပိုင်းများကို ဖွင့်ခြင်း သို့မဟုတ် ပိတ်ခြင်း"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"appအား အခြား app တစ်ခု၏ အစိတ်အပိုင်း တစ်ခုမှာ ဖွင့်ထားသည် ဖြစ်စေ ဖွင့်မထားသည် ဖြစ်စေ ပြောင်းလဲခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် တက်ဘလက်၏ လုပ်နိုင်စွမ်းကို ပိတ်ပစ်နိုင်သည်။ app၏ အစိတ်အပိုင်းများကို သုံးမရအောင်၊ စနစ်မမှန်အောင် သို့မဟုတ် အခြေအနေ မတည်ငြိမ်အောင် လုပ်၍ ရနိုင်သောကြောင့် ဒီ ခွင့်ပြုချက်ကို သုံးရာတွင် သတိထားရန် လိုအပ်သည်။"</string>
-    <string name="permdesc_changeComponentState" product="tv" msgid="9151634188264231389">"တစ်ခြား app ၏ အစိတ်အပိုင်းတစ်ခုအား ဖွင့်ထားခြင်း ရှိမရှိအား ပြောင်းလဲရန် app အား ခွင့်ပြုပါ။ တီဗွီ၏ အရေးကြီး လုပ်ဆောင်နိုင်မှုများအား ပိတ်ပစ်ရန် ၎င်းအား အန္တရာယ်ရှိသော app များက အသုံးပြုနိုင်သည်။ app ၏ အစိတ်အပိုင်းများ အသုံးပြု၍မရခြင်း၊ မတည်မငြိမ်ဖြစ်ခြင်း၊ သို့မဟုတ်  မတည်မြဲခြင်းများ ဖြစ်စေတတ်သောက​ြောင့်၊ ဤခွင့်ပြုချက်ကို သတိဖြင့် လုပ်ဆောင်ပါ။"</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"appအား အခြား app တစ်ခု၏ အစိတ်အပိုင်း တစ်ခုမှာ ဖွင့်ထားသည် ဖြစ်စေ ဖွင့်မထားသည် ဖြစ်စေ ပြောင်းလဲခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် ဖုန်း၏ လုပ်နိုင်စွမ်းကို ပိတ်ပစ်နိုင်သည်။ app၏ အစိတ်အပိုင်းများကို သုံးမရအောင်၊ စနစ်မမှန်အောင် သို့မဟုတ် အခြေအနေ မတည်ငြိမ်အောင် လုပ်၍ ရနိုင်သောကြောင့် ဒီ ခွင့်ပြုချက်ကို သုံးရာတွင် သတိထားရန် လိုအပ်သည်။"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"appအား diag အုပ်စု ပိုင်ဆိုင်သည့် မည်သည့် အရင်းအမြစ်ကို မဆို ရေးခြင်း နှင့် ဖတ်ခြင်းကို ခွင့်ပြုသည်၊ ဥပမာ၊ /dev ထဲက ဖိုင်များ။ ၎င်းက စနစ်၏ တည်ငြိမ်မှု နှင့် လုံခြုံမှုကို ထိပါးနိုင်သည့် အလားအလာ ရှိသည်။ ထုတ်လုပ်သူ သို့မဟုတ် အော်ပရေတာက ဟာ့ဒ်ဝဲ ဆိုင်ရာ ပြဿနာ ရှာဖွေ စူးစမ်းမှု အတွက်သာ ၎င်းကို အသုံးပြုရမည်။"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"app အစိတ်အပိုင်းများကို ဖွင့်ခြင်း သို့မဟုတ် ပိတ်ခြင်း"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"appအား အခြား app တစ်ခု၏ အစိတ်အပိုင်း တစ်ခုမှာ ဖွင့်ထားသည် ဖြစ်စေ ဖွင့်မထားသည် ဖြစ်စေ ပြောင်းလဲခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် တက်ဘလက်၏ လုပ်နိုင်စွမ်းကို ပိတ်ပစ်နိုင်သည်။ app၏ အစိတ်အပိုင်းများကို သုံးမရအောင်၊ စနစ်မမှန်အောင် သို့မဟုတ် အခြေအနေ မတည်ငြိမ်အောင် လုပ်၍ ရနိုင်သောကြောင့် ဒီ ခွင့်ပြုချက်ကို သုံးရာတွင် သတိထားရန် လိုအပ်သည်။"</string>
+    <string name="permdesc_changeComponentState" product="tv" msgid="9151634188264231389">"တစ်ခြား app ၏ အစိတ်အပိုင်းတစ်ခုအား ဖွင့်ထားခြင်း ရှိမရှိအား ပြောင်းလဲရန် app အား ခွင့်ပြုပါ။ တီဗွီ၏ အရေးကြီး လုပ်ဆောင်နိုင်မှုများအား ပိတ်ပစ်ရန် ၎င်းအား အန္တရာယ်ရှိသော app များက အသုံးပြုနိုင်သည်။ app ၏ အစိတ်အပိုင်းများ အသုံးပြု၍မရခြင်း၊ မတည်မငြိမ်ဖြစ်ခြင်း၊ သို့မဟုတ်  မတည်မြဲခြင်းများ ဖြစ်စေတတ်သောက​ြောင့်၊ ဤခွင့်ပြုချက်ကို သတိဖြင့် လုပ်ဆောင်ပါ။"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"appအား အခြား app တစ်ခု၏ အစိတ်အပိုင်း တစ်ခုမှာ ဖွင့်ထားသည် ဖြစ်စေ ဖွင့်မထားသည် ဖြစ်စေ ပြောင်းလဲခွင့် ပြုသည်။ အကြံအဖန် appများက ၎င်းကို အသုံးပြုပြီး အရေးကြီးသည့် ဖုန်း၏ လုပ်နိုင်စွမ်းကို ပိတ်ပစ်နိုင်သည်။ app၏ အစိတ်အပိုင်းများကို သုံးမရအောင်၊ စနစ်မမှန်အောင် သို့မဟုတ် အခြေအနေ မတည်ငြိမ်အောင် လုပ်၍ ရနိုင်သောကြောင့် ဒီ ခွင့်ပြုချက်ကို သုံးရာတွင် သတိထားရန် လိုအပ်သည်။"</string>
     <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ခွင့်ပြုချက် ထောက်ခံခြင်း သို့ ပယ်ဖျက်ခြင်း"</string>
     <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"အပလီကေးရှင်းအား ကိုယ်တိုင် ဒါမှမဟုတ် တခြား အပလီကေးရှင်းအတွက် ခွင့်ပြုချက်များအား ခွင့်ပြုခြင်း၊ပယ်ဖျယ်ခြင်း လုပ်ခွင့်ပြုပါ။ အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ဒီခွင့်ပြုချက်အားသုံးပြီး အခွင့်မရှိသော စွမ်းဆောင်ချက်များအား သုံးနိုင်ပါသည်"</string>
-    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ပိုကြိုက်သည့် appများကို သတ်မှတ်ခြင်း"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"appအား သင် နှစ်ခြုက်သည့် appများကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက ဖွင့်ထားသည့် appများကို တိတ်တဆိတ် ပြောင်းလဲပစ်ကာ၊ ရှိနေကြသည့် သင်၏ appများကို သင့်ထံမှ သင်၏ ကိုယ်ရေး ဒေတာများကို စုစည်းရန် ခိုင်းနိုင်သည်။"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ပိုကြိုက်သည့် appများကို သတ်မှတ်ခြင်း"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"appအား သင် နှစ်ခြုက်သည့် appများကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက ဖွင့်ထားသည့် appများကို တိတ်တဆိတ် ပြောင်းလဲပစ်ကာ၊ ရှိနေကြသည့် သင်၏ appများကို သင့်ထံမှ သင်၏ ကိုယ်ရေး ဒေတာများကို စုစည်းရန် ခိုင်းနိုင်သည်။"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"စနစ်အပြင်အဆင်အား မွမ်းမံခြင်း"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"appအား စနစ်၏ ဆက်တင် ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများက သင့် စနစ်၏ စီစဉ်ဖွဲ့စည်းမှုကို ဖျက်ဆီးပစ်နိုင်သည်။"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"appအား စနစ်၏ ဆက်တင် ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများက သင့် စနစ်၏ စီစဉ်ဖွဲ့စည်းမှုကို ဖျက်ဆီးပစ်နိုင်သည်။"</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"စနစ်အပြင်အဆင်လုံခြုံမှုအား မွမ်းမံခြင်း"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"appအား စနစ်၏ လုံခြုံစိတ်ချရသည့် ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"appအား စနစ်၏ လုံခြုံစိတ်ချရသည့် ဒေတာကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"ဂူဂဲလ်ဝန်ဆောင်မှုမြေပုံအားမွမ်းမံခြင်း"</string>
-    <string name="permdesc_writeGservices" msgid="1287309437638380229">"appအယဒ Google ဝန်ဆောင်မှုများ မြေပုံကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"appအယဒ Google ဝန်ဆောင်မှုများ မြေပုံကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"အစတွင် လုပ်ဆောင်ရန်"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"appအား စနစ်၏ စတင်မှု ပြီးဆုံးသည့်နှင့် မိမိကိုမိမိ စတင်ခွင့် ပြုသည်။ သို့ဖြစ်၍ ဖုန်း စတင်မှုမှာ အချိန် ပိုကြာနိုင်ပြီး appက တချိန်လုံး အလုပ်လုပ်နေခြင်းကြောင့် တက်ဘလက်၏ အလုပ် တစ်ခုလုံးကို နှေးကွေးလာစေနိုင်သည်။"</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"စနစ် စတင်ပြီးသည်နှင့် တစ်ပြိုင်နက် အလိုလို အစပြုရန် app အားခွင့်ပြုပါ။ ထိုသို့ခွင့်ပြုခြင်းဖြင့် တီဗွီအား စရန် အချိန်ကြာစေပြီး အစဉ်အမြဲဖွင့်ထားခြင်းဖြင့် တက်ဘလက်အား နှေးသွားစေရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"appအား စနစ်၏ စတင်မှု ပြီးဆုံးသည့်နှင့် မိမိကိုမိမိ စတင်ခွင့် ပြုသည်။ သို့ဖြစ်၍ ဖုန်း စတင်မှုမှာ အချိန် ပိုကြာနိုင်ပြီး appက တချိန်လုံး အလုပ်လုပ်နေခြင်းကြောင့် ဖုန်း၏ အလုပ် တစ်ခုလုံးကို နှေးကွေးလာစေနိုင်သည်။"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"appအား စနစ်၏ စတင်မှု ပြီးဆုံးသည့်နှင့် မိမိကိုမိမိ စတင်ခွင့် ပြုသည်။ သို့ဖြစ်၍ ဖုန်း စတင်မှုမှာ အချိန် ပိုကြာနိုင်ပြီး appက တချိန်လုံး အလုပ်လုပ်နေခြင်းကြောင့် တက်ဘလက်၏ အလုပ် တစ်ခုလုံးကို နှေးကွေးလာစေနိုင်သည်။"</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"စနစ် စတင်ပြီးသည်နှင့် တစ်ပြိုင်နက် အလိုလို အစပြုရန် app အားခွင့်ပြုပါ။ ထိုသို့ခွင့်ပြုခြင်းဖြင့် တီဗွီအား စရန် အချိန်ကြာစေပြီး အစဉ်အမြဲဖွင့်ထားခြင်းဖြင့် တက်ဘလက်အား နှေးသွားစေရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"appအား စနစ်၏ စတင်မှု ပြီးဆုံးသည့်နှင့် မိမိကိုမိမိ စတင်ခွင့် ပြုသည်။ သို့ဖြစ်၍ ဖုန်း စတင်မှုမှာ အချိန် ပိုကြာနိုင်ပြီး appက တချိန်လုံး အလုပ်လုပ်နေခြင်းကြောင့် ဖုန်း၏ အလုပ် တစ်ခုလုံးကို နှေးကွေးလာစေနိုင်သည်။"</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"ကြာရှည်ခံ ထုတ်လွှတ်မှု အားပေးပို့ခြင်း"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"အပလီကေးရှင်းအား ကြာရှည်ခံ ထုတ်လွှင့်မှု ပြုပါ။ ဒီထုတ်လွှင့်မှုများဟာ ထုတ်လွှင့်မှု ပြီးဆုံးပြီးသွားတည့်တိုင် ကျန်နေမည် ဖြစ်ပါသည်။ အလွန်အကျွံသုံးခြင်းကြောင့် မက်မိုရီ အသုံးများပြီး တက်ဘလက်နှေးခြင်း၊ မတည်ငြိမ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
-    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"ထုတ်လွှင့်ခြင်းများ ပြီးဆုံးသည့်နောက် ဆက်လက်ရှိနေသည့်၊ တည်မြဲ ထုတ်လွှင့်မှုများပို့ရန် app အား ခွင့်ပြုပါ။ အလွန်အကျွံ လုပ်ဆောင်ပါက တီဗွီ နှေးသွားခြင်း သို့မဟုတ် မှတ်ဉာဏ်အသုံးများမှုကြောင့် မတည်မငြိမ်ဖြစ်ခြင်းများ ဖြစ်တတ်၏။"</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"ထုတ်လွှင့်ခြင်းများ ပြီးဆုံးသည့်နောက် ဆက်လက်ရှိနေသည့်၊ တည်မြဲ ထုတ်လွှင့်မှုများပို့ရန် app အား ခွင့်ပြုပါ။ အလွန်အကျွံ လုပ်ဆောင်ပါက တီဗွီ နှေးသွားခြင်း သို့မဟုတ် မှတ်ဉာဏ်အသုံးများမှုကြောင့် မတည်မငြိမ်ဖြစ်ခြင်းများ ဖြစ်တတ်၏။"</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"အပလီကေးရှင်းအား ကြာရှည်ခံ ထုတ်လွှင့်မှု ပြုပါ။ ဒီထုတ်လွှင့်မှုများဟာ ထုတ်လွှင့်မှု ပြီးဆုံးပြီးသွားတည့်တိုင် ကျန်နေမည် ဖြစ်ပါသည်။ အလွန်အကျွံသုံးခြင်းကြောင့် မှတ်ဉာဏ်အသုံးများပြီး ဖုန်းနှေးခြင်း၊ မတည်ငြိမ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"အဆက်အသွယ်များအား ဖတ်ခြင်း"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"အပလီကေးရှင်းအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်အကြိမ်ရေ၊ တခြားဆက်သွယ်မှုများစသည်ကဲ့သို့ သင့်တက်ဘလက်မှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက်ကို ဖတ်ခွင့်ပြုပါ။ ဤသို့ခွင့်ပြုခြင်းအားဖြင့် အပလီကေးရှင်းများကို သင့် အဆက်အသွယ်၏ အချက်မလက်များကို သိမ်းဆည်းရန် ခွင့်ပြုပြီး အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ထိုအချက်အလက်များ ကို သင် မသိစေပဲ ဖြန့်ဝေနိုင််မည် ဖြစ်ပါသည်။"</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"တစ်ဦးတစ်​ယောက်ထံ သင်ခေါ်ထားသော၊ အီးမေးိပု့ထားသော၊ သို့မဟုတ် တစ်ခြားနည်းဖြင့် အဆက်အသွယ်ပြုထားသော အကြိမ်အရေအတွက် အပါအဝင်၊ သင့်တီဗွီတွင် သိမ်းထားသည့် အဆက်အသွယ်ဆိုင်ရာ အချက်အလက်များ ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် သင့် အဆက်အသွယ် အချက်အလက်များအား သိမ်းဆည်းရန် app အား ခွင့်ပြုထားခြင်းဖြစ်ပြီး၊  အဆက်အသွယ် အချက်အလက်များအား အန္တရာယ်ရှိသော app များက သင်မသိဘဲ ဝေမျှနိုင်သည်။"</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"တစ်ဦးတစ်​ယောက်ထံ သင်ခေါ်ထားသော၊ အီးမေးိပု့ထားသော၊ သို့မဟုတ် တစ်ခြားနည်းဖြင့် အဆက်အသွယ်ပြုထားသော အကြိမ်အရေအတွက် အပါအဝင်၊ သင့်တီဗွီတွင် သိမ်းထားသည့် အဆက်အသွယ်ဆိုင်ရာ အချက်အလက်များ ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် သင့် အဆက်အသွယ် အချက်အလက်များအား သိမ်းဆည်းရန် app အား ခွင့်ပြုထားခြင်းဖြစ်ပြီး၊  အဆက်အသွယ် အချက်အလက်များအား အန္တရာယ်ရှိသော app များက သင်မသိဘဲ ဝေမျှနိုင်သည်။"</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"အပလီကေးရှင်းအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်အကြိမ်ရေ၊ တခြားဆက်သွယ်မှုများစသည်ကဲ့သို့ သင့်ဖုန်းမှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက်ကို ဖတ်ခွင့်ပြုပါ။ ဤသို့ခွင့်ပြုခြင်းအားဖြင့် အပလီကေးရှင်းများကို သင့် အဆက်အသွယ်၏ အချက်မလက်များကို သိမ်းဆည်းရန် ခွင့်ပြုပြီး အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ထိုအချက်အလက်များ ကို သင် မသိစေပဲ ဖြန့်ဝေနိုင််မည် ဖြစ်ပါသည်။"</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"အဆက်အသွယ်များအား ပြင်ဆင်ခြင်း"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"အပလီကေးရှင်းအား သင့်တက်ဘလက်မှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက် (အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ) ကို ပြင်ဆင်ခွင့်ပြုခြင်း။ ဒီခွင့်ပြုချက်က အပလီကေးရှင်းများအား အဆက်အသွယ် အချက်အလက်များ ဖျက်စီးခြင်း လုပ်ဆောင်စေနိုင်မှာ ဖြစ်ပါသည်။"</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ အပါအဝင်၊ သင့်တီဗွီတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်အား ပြင်ဆင်ရန် အပလီကေးရှင်းအား ခွင့်ပြုပါ။ ဤသို့ ခွင့်ပြုခြင်းသည် အဆက်အသွယ် အချက်အလက်များ ဖျက်ဆီးရန် အပလီကေးရှင်းများအား  ခွင့်ပြုခြင်းဖြစ်၏။"</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ အပါအဝင်၊ သင့်တီဗွီတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်အား ပြင်ဆင်ရန် အပလီကေးရှင်းအား ခွင့်ပြုပါ။ ဤသို့ ခွင့်ပြုခြင်းသည် အဆက်အသွယ် အချက်အလက်များ ဖျက်ဆီးရန် အပလီကေးရှင်းများအား  ခွင့်ပြုခြင်းဖြစ်၏။"</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"အပလီကေးရှင်းအား သင့်ဖုန်းမှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက် (အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ) ကို ပြင်ဆင်ခွင့်ပြုခြင်း။ ဒီခွင့်ပြုချက်က အပလီကေးရှင်းများအား အဆက်အသွယ် အချက်အလက်များ ဖျက်စီးခြင်း လုပ်ဆောင်စေနိုင်မှာ ဖြစ်ပါသည်။"</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"ခေါ်ဆိုမှု မှတ်တမ်းအား ဖတ်ခြင်း"</string>
     <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"အပလီကေးရှင်းအား တက်ဘလက်၏ အထွက် အဝင် ခေါ်ဆိုမှုများ အပါအဝင် ခေါ်ဆိုမှု မှတ်တမ်းအား ကြည့်ရှုခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် ခေါ်ဆိုမှု မှတ်တမ်းအား သိုလှောင်ခြင်း၊ မျှဝေခြင်းများကို သင် မသိရှိပဲ ပြုလုပ်နိုင်မှာ ဖြစ်ပါသည်"</string>
-    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"အဝင်အထွက် ခေါ်ဆိုထားသော ဒေတာများ အပါအဝင်၊ သင့် တီဗွီ၏ ခေါ်ဆိုမှု မှတ်တမ်းအား ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် သင့် ခေါ်ဆိုမှုမှတ်တမ်းဒေတာကို သိမ်းဆည်းရန် app အား ခွင့်ပြုပြီး၊ အန္တရာယ်ရှိသော app များက သင်အား အသိမပေးဘဲ ခေါ်ဆိုမှုမှတ်တမ်းဒေတာကို ဝေမျှနိုင်သည်။"</string>
+    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"အဝင်အထွက် ခေါ်ဆိုထားသော ဒေတာများ အပါအဝင်၊ သင့် တီဗွီ၏ ခေါ်ဆိုမှု မှတ်တမ်းအား ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် သင့် ခေါ်ဆိုမှုမှတ်တမ်းဒေတာကို သိမ်းဆည်းရန် app အား ခွင့်ပြုပြီး၊ အန္တရာယ်ရှိသော app များက သင်အား အသိမပေးဘဲ ခေါ်ဆိုမှုမှတ်တမ်းဒေတာကို ဝေမျှနိုင်သည်။"</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"အပလီကေးရှင်းအား ဖုန်း၏ အဝင်အထွက် ခေါ်ဆိုမှုများ အပါအဝင် ခေါ်ဆိုမှု မှတ်တမ်းအား ကြည့်ရှုခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် ခေါ်ဆိုမှု မှတ်တမ်းအား သိုလှောင်ခြင်း၊ မျှဝေခြင်းများကို သင် မသိရှိပဲ ပြုလုပ်နိုင်မှာ ဖြစ်ပါသည်။"</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"ခေါ်ဆိုမှုမှတ်တမ်း ရေးသားခြင်း"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"အပလီကေးရှင်းအား သင့်တက်ဘလက်၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်း (အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ) ကို ပြင်ဆင်ခွင့် ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်"</string>
@@ -520,34 +520,34 @@
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"အပလီကေးရှင်းအား စက်မှာ သိမ်းထားသော သင့်နာမည် နှင့် အဆက်အသွယ် သတင်းအချက်အလက်များကဲ့သို့သော ကိုယ်ရေးကိုယ်တာ အချက်အလက်များအား ဖတ်ခွင့် ပြုခြင်း။ အပလီကေးရှင်းမှ သင့်အား သိရှိနိုင်ပြီး သင့်ကိုယ်ရေးအချက်အလက်များအား အခြားသူများကို ပေးပို့နိုင်ပါသည်"</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"သင့်ရဲ့ အဆက်အသွယ်ကဒ် အား ပြင်ရန်"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"အပလီကေးရှင်းအား စက်မှာ သိမ်းထားသော သင့်နာမည် နှင့် အဆက်အသွယ် သတင်းအချက်အလက်များကဲ့သို့သော ကိုယ်ရေးကိုယ်တာ အချက်အလက်များအား ပြင်ဆင်ခွင့် သို့ ထည့်ခွင့် ပြုခြင်း။ အပလီကေးရှင်းမှ သင့်အား သိရှိနိုင်ပြီး သင့်ကိုယ်ရေးအချက်အလက်များအား အခြားသူများကို ပေးပို့နိုင်ပါသည်"</string>
-    <string name="permlab_bodySensors" msgid="4871091374767171066">"ခန္ဓာကိုယ် အာရံခံကိရိယာများ (နှလုံးခုန်နှုန်း စောင့်ကြည့်စက် လို)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"သင်၏ နှလုံးခုန်နှုန်းလို ရုပ်ပိုင်း အခြေအနေကို စောင့်ကြပ်သည့် အာရုံခံစက်များထံမှ ဒေတာများကို appအား ရယူသုံးခွင့် ပြုပါ။"</string>
-    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
+    <string name="permlab_bodySensors" msgid="4871091374767171066">"ခန္ဓာကိုယ် အာရံခံကိရိယာများ (နှလုံးခုန်နှုန်း စောင့်ကြည့်စက် လို)"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"သင်၏ နှလုံးခုန်နှုန်းလို ရုပ်ပိုင်း အခြေအနေကို စောင့်ကြပ်သည့် အာရုံခံစက်များထံမှ ဒေတာများကို appအား ရယူသုံးခွင့် ပြုပါ။"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"အပလီကေးရှင်းအား သင်နှင့် သင့်သူငယ်ချင်းတို့၏ ဆိုရှယ်နက်ဝဘ်မှ နောက်ဆုံးပေါ် အချက်အလက်များအား အသုံးပြုခွင့်နင့် ထပ်တူညီအောင် လုပ်ဆောင်ခွင့် ပြုပါ။ သတင်းအချက်အလက် မျှဝေခြင်းတွင် သတိပြုရန် -- ဤသို့ ခွင့်ပြုခြင်းဖြင့် အပလီကေးရှင်းမှ ယုံကြည်စိတ်ချရမှုကို ဂရုမပြုပဲ သင် နှင့် သူငယ်ချင်းများကြား ဆက်သွယ်မှုများအား သိရှိနိုင်ပါသည်။ မှတ်ချက်။ ဤခွင့်ပြုချက်အား ဆိုရှယ်နက်ဝဘ် အားလုံးတွင် ခွင့်ပြုခြင်း မလုပ်သင့်ပါ။"</string>
-    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"အပလီကေးရှင်းအား သူငယ်ချင်းများရဲ့ ဆိုရှယ်နက်ဝဘ်မှနောက်ဆုံးပေါ် အချက်အလက်များအား ဖန်သားပြင်ပေါ်တွင် ပြခွင့်ပြုရန်။ သတင်းအချက်အလက် မျှဝေခြင်းတွင် သတိပြုရန် -- ဤသို့ ခွင့်ပြုခြင်းဖြင့် အပလီကေးရှင်းမှ  သူငယ်ချင်းများထံမှ လာသကဲ့သို့ သတင်းများ ပြုလုပ်နိုင်ပါသည်။ မှတ်ချက်၊ ဤခွင့်ပြုချက်အား ဆိုရှယ်နက်ဝဘ် အားလုံးတွင် ခွင့်ပြုခြင်း မလုပ်သင့်ပါ။"</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"ပြက္ခဒိန်အဖြစ်အပျက်များနှင့် လှို့ဝှက်အချက်အလက်များအား ဖတ်ခြင်း"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"ပြက္ခဒိန်အဖြစ်အပျက်များနှင့် လှို့ဝှက်အချက်အလက်များအား ဖတ်ခြင်း"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"အပလီကေးရှင်းအား တက်ဘလက်ထဲတွင် သိမ်းထားသော သူငယ်ချင်းနှင့် လုပ်ဖော်ကိုင်ဘက်များ၏ ပြက္ခဒိန် အဖြစ်အပျက်များအပါအဝင် အားလုံးကို ဖတ်ရှုခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် အပလီကေးရှင်းမှ ပြက္ခဒိန် အဖြစ်အပျက်များအား လျှို့ဝှက်မှု သို့ ဂရုပြုမှု ကို ထည့်သွင်းမစဉ်းစားပဲ သိမ်းဆည်းခြင်း၊ မျှဝေခြင်း ပြုလုပ်စေနိုင်ပါသည်"</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ ဖြစ်ရပ်များ အပါအဝင်၊ သင့် တီဗွီတွင် သိမ်းထားသော ပြက္ခဒိန်ရှိ ဖြစ်ရပ်များအား ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် ယုံကြည်စိတ်ချရမှု သို့မဟုတ် ထိခိုက်လွယ်မှုတို့နှင့် မသက်ဆိုင်ဘဲ၊ သင့် ပြက္ခဒိန်ရှိ ဒေတာကို ဝေမျှရန် သို့မဟုတ် သိမ်းဆည်းရန် app အား ခွင့်ပြုသည်။"</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ ဖြစ်ရပ်များ အပါအဝင်၊ သင့် တီဗွီတွင် သိမ်းထားသော ပြက္ခဒိန်ရှိ ဖြစ်ရပ်များအား ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် ယုံကြည်စိတ်ချရမှု သို့မဟုတ် ထိခိုက်လွယ်မှုတို့နှင့် မသက်ဆိုင်ဘဲ၊ သင့် ပြက္ခဒိန်ရှိ ဒေတာကို ဝေမျှရန် သို့မဟုတ် သိမ်းဆည်းရန် app အား ခွင့်ပြုသည်။"</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"အပလီကေးရှင်းအားဖုန်းထဲတွင် သိမ်းထားသော သူငယ်ချင်းနှင့် လုပ်ဖော်ကိုင်ဘက်များ၏ ပြက္ခဒိန် အဖြစ်အပျက်များအပါအဝင် အားလုံးကို ဖတ်ရှုခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် အပလီကေးရှင်းမှ ပြက္ခဒိန် အဖြစ်အပျက်များအား လျှို့ဝှက်မှု သို့ ဂရုပြုမှု ကို ထည့်သွင်းမစဉ်းစားပဲ သိမ်းဆည်းခြင်း၊ မျှဝေခြင်း ပြုလုပ်စေနိုင်ပါသည်"</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ပြက္ခဒိန်အဖြစ်အပျက်များကို ထပ်ထည့်ရန် သို့မဟုတ် မွမ်းမံရန်နှင့် ပိုင်ရှင်၏အသိမပေးပဲ ဧည့်သည်များထံ အီးမေးလ်ပို့ရန်"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ပြက္ခဒိန်အဖြစ်အပျက်များကို ထပ်ထည့်ရန် သို့မဟုတ် မွမ်းမံရန်နှင့် ပိုင်ရှင်၏အသိမပေးပဲ ဧည့်သည်များထံ အီးမေးလ်ပို့ရန်"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"အပလီကေးရှင်းအား သင်၏ တက်ဘလက်တွင် သူငယ်ချင်း အလုပ်ဖော်များ အပါအဝင် သင်၏ ပြောင်းလဲအဖြစ်အပျက်များအား ထည့်ခြင်း၊ ထုတ်ခြင်းအား ခွင့်ပြုရန်။ ဤခွင့်ပြုချက်သည် အပလီကေးရှင်းအား သတင်းများပို့ခြင်းကို ပြက္ခဒိန်ပိုင်ရှင်ဆီမှ လာသလို အနေဖြင့် ပေးပို့ခြင်း သို့မဟုတ် အဖြစ်အပျက်များကို ပိုင်ရှင်မသိပဲ ပြင်ဆင်နိုင်ပါသည်။"</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"သင့် သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ လှုပ်ရှားမှုများ အပါအဝင်၊ သင့်တီဗွီရှိ လှုပ်ရှားမှုများကို ထပ်ထည့်ရန်၊ ဖယ်ထုတ်ရန်၊ ပြောင်းလဲရန် app အား ခွင့်ပြုပါ။ ဤသို့ပြုပါက ပြက္ခဒိန် ပိုင်ရှင်ဆီမှ စာတိုများ လာသကဲ့သို့ စာများပို့ရန်၊ သို့မဟုတ် ပိုင်ရှင်၏ ခွင့်ပြုချက်မရှိဘဲ လှုပ်ရှားမှုများကို ပြင်ဆင်ရန် app အား ခွင့်ပြုထားခြင်း ဖြစ်၏။"</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"သင့် သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ လှုပ်ရှားမှုများ အပါအဝင်၊ သင့်တီဗွီရှိ လှုပ်ရှားမှုများကို ထပ်ထည့်ရန်၊ ဖယ်ထုတ်ရန်၊ ပြောင်းလဲရန် app အား ခွင့်ပြုပါ။ ဤသို့ပြုပါက ပြက္ခဒိန် ပိုင်ရှင်ဆီမှ စာတိုများ လာသကဲ့သို့ စာများပို့ရန်၊ သို့မဟုတ် ပိုင်ရှင်၏ ခွင့်ပြုချက်မရှိဘဲ လှုပ်ရှားမှုများကို ပြင်ဆင်ရန် app အား ခွင့်ပြုထားခြင်း ဖြစ်၏။"</string>
     <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"အပလီကေးရှင်းအား သင်၏ ဖုန်းတွင် သူငယ်ချင်း အလုပ်ဖော်များ အပါအဝင် သင်၏ ပြောင်းလဲအဖြစ်အပျက်များအား ထည့်ခြင်း၊ ထုတ်ခြင်းအား ခွင့်ပြုရန်။ ဤခွင့်ပြုချက်သည် အပလီကေးရှင်းအား သတင်းများပို့ခြင်းကို ပြက္ခဒိန်ပိုင်ရှင်ဆီမှ လာသလို အနေဖြင့် ပေးပို့ခြင်း သို့မဟုတ် အဖြစ်အပျက်များကို ပိုင်ရှင်မသိပဲ ပြင်ဆင်နိုင်ပါသည်။"</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"စမ်းသပ်ရန်အတွက် တည်နေရာပုံစံတုမူရင်း"</string>
     <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"စမ်းသပ်ရန် သို့ နေရာပြပံ့ပို့းမှု အသစ်သွင်းရန် တည်နေရာဇစ်မြစ်အတုကို ဖန်တီးပါ။ ဤသို့လုပ်ခြင်းအားဖြင့် အပလီကေးရှင်းမှ တည်နေရာကို ကျော်ဖြတ်ပြင်ဆင်ခြင်းနှင်ူ ဂျီပီအက်စ် သို့ နေရာပြပံ့ပိုးမှုကဲ့သို့သော အခြား တည်နေရာဇစ်မြစ်များ၏ အခြေအနေကို ပြန်ပို့ပေးနိုင်မည်ဖြစ်သည်။"</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"တည်နေရာပံ့ပိုးမှုညွှန်ကြားချက်အပိုအား ဝင်ရောက်ကြည့်ခြင်း"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"appအား တည်နေရာ စီမံပေးရေး ညွှန်ကြားချက် အပိုများကို ရယူခွင့်ပြုသည်။ သို့ဖြစ်၍ appသည် GPS သို့မဟုတ် အခြား တည်နေရာ ရင်းမြစ်ကို သုံးကြသူတို့၏ လုပ်ငန်းများကို ဝင်စွက်ခွင့် ပြုနိုင်သည်။"</string>
-    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"တည်နေရာဝန်ဆောင်မှုပေးသူအားထည့်သွင်းရန်ခွင့်ပြုခြင်း"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"တည်နေရာပံ့ပိုးမှုညွှန်ကြားချက်အပိုအား ဝင်ရောက်ကြည့်ခြင်း"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"appအား တည်နေရာ စီမံပေးရေး ညွှန်ကြားချက် အပိုများကို ရယူခွင့်ပြုသည်။ သို့ဖြစ်၍ appသည် GPS သို့မဟုတ် အခြား တည်နေရာ ရင်းမြစ်ကို သုံးကြသူတို့၏ လုပ်ငန်းများကို ဝင်စွက်ခွင့် ပြုနိုင်သည်။"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"တည်နေရာဝန်ဆောင်မှုပေးသူအားထည့်သွင်းရန်ခွင့်ပြုခြင်း"</string>
     <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"စမ်းသပ်ရန် သို့ နေရာပြပံ့ပို့းမှု အသစ်သွင်းရန် တည်နေရာဇစ်မြစ်အတုကို ဖန်တီးပါ။ ဤသို့လုပ်ခြင်းအားဖြင့် အပလီကေးရှင်းမှ တည်နေရာကို ကျော်ဖြတ်ပြင်ဆင်ခြင်းနှင်ူ ဂျီပီအက်စ် သို့ နေရာပြပံ့ပိုးမှုကဲ့သို့သော အခြား တည်နေရာဇစ်မြစ်များ၏ အခြေအနေကို ပြန်ပို့ပေးနိုင်မည်ဖြစ်သည်။"</string>
     <string name="permlab_accessFineLocation" msgid="1191898061965273372">"တည်နေရာ အတိအကျ (ဂျီပီအက်စ် နှင့် ကွန်ရက်အခြေခံ)"</string>
     <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"အပလီကေးရှင်းမှ သင့်ရဲ့ တိကျသောနေရာကို ဂျီပီအက်စ် သို့ ဆယ်လူလာတာဝါတိုင်၊ ဝိုင်ဖိုင် အချက်အလက်များ သုံးပြီး ရှာခြင်း ခွင့်ယူပါ။ နေရာပြ ဆားဗစ်များ စက်ပေါ်မှာ ရှိရမှာ ဖြစ်သလို ဖွင့်ထားရမှာလည်း ဖြစ်ပါသည်။ အပလီကေးရှင်းမှ ဒီဆားဗစ်များကို သုံး၍ ရှာဖွေသောကြောင့် ဘက်ထရီ ပိုကုန်နိုင်ပါသည်။"</string>
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"အကြမ်းဖျင်းနေရာ (ကွန်ရက်အခြေခံ)"</string>
     <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"သင့်ရဲ့ ပျမ်းမျတည်နေရာကို အပလီကေးရှင်း အား သိခွင့် ပြုရန်။ ဒီ တည်နေရာကို တည်နေရာရှာဖွေရေး ဆားဗစ်မှ မိုဘိုင်း တာဝါတိုင်၊ ဝိုင်ဖိုင် စသည်တို့မှ တဆင့် ရယူပါသည်။  အပလီကေးရှင်း အနေဖြင့် ဒီ ဆားဗစ်များ ရှိနေရန် လိုအပ်ပါသည်။ ဒီအရာများကို အသုံးပြု၍ သင့်နေရာကို သိနိုင်ပါသည်။"</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlingerအား ချိတ်ဆက်ရန်"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ဒီ appအား InputFlinger အဆင့်နိမ့် အင်္ဂါရပ်များကို သုံးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ဒီ appအား InputFlinger အဆင့်နိမ့် အင်္ဂါရပ်များကို သုံးခွင့် ပြုသည်။"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"frame bufferအားဖတ်ခြင်း"</string>
-    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"appအား ဘောင် စပ်ကြား နေရာ ထဲက အကြောင်းအရာကို ဖတ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"appအား ဘောင် စပ်ကြား နေရာ ထဲက အကြောင်းအရာကို ဖတ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger အား သုံးခွင့်"</string>
     <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"အပလီကေးရှင်းကို InputFlinger low-level features ပေးသုံးခြင်း"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"ဝိုင်ဖိုင်ဖြင့် ပြသမှုအား ပြင်ဆင်ရန်"</string>
@@ -555,26 +555,26 @@
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ဝိုင်ဖိုင်ဖြင့် ပြသမှု အား ထိန်းချုပ်ရန်"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"အပလီကေးရှင်းအား စက်ရဲ့ အနိမ့်ပိုင်းမှာ ရှိသော ဝိုင်ဖိုင် ပြသမှုအား ထိန်းချုပ်ခွင့်ပြုပါ"</string>
     <string name="permlab_controlVpn" msgid="2618442789397588200">"ကိုယ်ပိုင်ကွန်ယက်အတုကို ထိန်းချုပ်ရန်"</string>
-    <string name="permdesc_controlVpn" msgid="762852603315861214">"ကိုယ်ပိုင်ကွန်ယက်အတု၏ အရည်အသွေးနိမ့်လုပ်ဆောင်ချက်များကို ထိန်းချုပ်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"ကိုယ်ပိုင်ကွန်ယက်အတု၏ အရည်အသွေးနိမ့်လုပ်ဆောင်ချက်များကို ထိန်းချုပ်ရန် app အား ခွင့်ပြုပါ။"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"အသံထွက်မှု အား ဖမ်းယူခြင်း"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"အပလီကေးရှင်းကို အသံဖမ်းခွင့် လမ်းကြောင်းလွှဲခွင့်များ ခွင့်ပြုခြင်း"</string>
-    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"အသံဖြင့်ညွှန်ကြားရန်အတိုကောက်များအား ဖမ်းယူ သိနိုင်မှု"</string>
-    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"အပလီကေးရှင်းကို အသံဖြင့်ညွှန်းကြားရန်အတိုကောက်များ အတွက် အသံဖမ်းယူခွင့်ပြုခြင်း။ နောက်ကွယ်မှာ ဖြစ်နိုင်ပေမယ့် တခြားအသံဖမ်းခြင်းများ (ဥပမာ ရုပ်သံဖမ်းစက်) များကို ပိတ်ပင်မှု မဖြစ်စေပါ"</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"အသံဖြင့်ညွှန်ကြားရန်အတိုကောက်များအား ဖမ်းယူ သိနိုင်မှု"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"အပလီကေးရှင်းကို အသံဖြင့်ညွှန်းကြားရန်အတိုကောက်များ အတွက် အသံဖမ်းယူခွင့်ပြုခြင်း။ နောက်ကွယ်မှာ ဖြစ်နိုင်ပေမယ့် တခြားအသံဖမ်းခြင်းများ (ဥပမာ ရုပ်သံဖမ်းစက်) များကို ပိတ်ပင်မှု မဖြစ်စေပါ"</string>
     <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"အသံ လမ်းကြောင်း"</string>
-    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"အက်ပ်အား အသံ လမ်းကြောင်းကို တိုက်ရိုက် ထိန်းချုပ်ခွင့် နှင့် အသံ မူဝါဒ ဆုံးဖြတ်ချက်များကို ကျော်ပြီးလုပ်ပိုင်ခွင့် ပေးသည်။"</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"အက်ပ်အား အသံ လမ်းကြောင်းကို တိုက်ရိုက် ထိန်းချုပ်ခွင့် နှင့် အသံ မူဝါဒ ဆုံးဖြတ်ချက်များကို ကျော်ပြီးလုပ်ပိုင်ခွင့် ပေးသည်။"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ရုပ်သံလွှင့်မှုအား ဖမ်းယူရန်"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"အပလီကေးရှင်းကို ရုပ်သံဖမ်းခွင့် လမ်းကြောင်းလွှဲခွင့်များ ခွင့်ပြုခြင်း"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"လုံခြုံသော ရုပ်သံလွှင့်မှုအား ဖမ်းယူရန်"</string>
     <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"အပလီကေးရှင်းကို လုံးခြုံစိတ်ချရသော အသံဖမ်းခြင်း လမ်းကြောင်းလွှဲခွင့်များ ခွင့်ပြုခြင်း"</string>
     <string name="permlab_mediaContentControl" msgid="8749790560720562511">"မီဒီယာ ပလေးဘက် နဲ့ မက်တာဒေတာ အသုံးပြုခွင့် အား ထိန်းချုပ်ခြင်း"</string>
     <string name="permdesc_mediaContentControl" msgid="1637478200272062">"အပလီကေးရှင်းအား ရုပ်သံ ပြန်လည်ပြသမှု နှင့် မီဒီယာ အချက်အလက် (ခေါင်းစဉ်၊ ရေးသားသူ) များကို ထိန်းချုပ်ခွင့် ပေးခြင်း"</string>
-    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"သင့်အသံအပြင်အဆင်အားပြောင်းခြင်း"</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"သင့်အသံအပြင်အဆင်အားပြောင်းခြင်း"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"အပလီကေးရှင်းအား အသံအတိုးအကျယ်နှင့် အထွက်ကို မည်သည့်စပီကာကို သုံးရန်စသည်ဖြင့် စက်တစ်ခုလုံးနှင့်ဆိုင်သော အသံဆိုင်ရာ ဆက်တင်များ ပြင်ဆင်ခွင့် ပြုရန်"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"အသံဖမ်းခြင်း"</string>
-    <string name="permdesc_recordAudio" msgid="4906839301087980680">"အပလီကေးရှင်းအား မိုက်ခရိုဖုန်းဖြင့် အသံသွင်းခွင့် ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် သင့် ခွင့်ပြုချက် မပါပဲ အချိန်မရွေး အသံဖမ်းနိုင်ပါမည်"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"အပလီကေးရှင်းအား မိုက်ခရိုဖုန်းဖြင့် အသံသွင်းခွင့် ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် သင့် ခွင့်ပြုချက် မပါပဲ အချိန်မရွေး အသံဖမ်းနိုင်ပါမည်"</string>
     <string name="permlab_sim_communication" msgid="1180265879464893029">"ဆင်းမ်ကဒ် ဆက်သွယ်ရေး"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"အပလီကေးရှင်းအား ဆင်းမ်ကဒ်ဆီသို့ အမိန့်များ ပေးပို့ခွင့် ပြုခြင်း။ ဒီ ခွင့်ပြုမှုဟာ အန်တရယ် အလွန် ရှိပါသည်။."</string>
-    <string name="permlab_camera" msgid="3616391919559751192">"ဓါတ်ပုံနှင့်ဗွီဒီယိုရိုက်ခြင်း"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ဓါတ်ပုံနှင့်ဗွီဒီယိုရိုက်ခြင်း"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"အပလီကေးရှင်းအား အလိုအလျောက် ဓာတ်ပုံရိုက်ခွင့်၊ ဗီဒီယို ရိုက်ကူးခွင့် ပြုပါ။ ဒီခွင့်ပြုချက်က အပလီကေးရှင်းကို အချိန်မရွေး ကင်မရာအား ခွင့်ပြုချက် မလိုအပ်ပဲ သုံးခွင့်ပြုပါသည်။"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ထုတ်လွှင့်မှုပြ အချက်ပေး မီးအား ကင်မရာ သုံးနေစဉ် ပိတ်ရန်"</string>
     <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ကြိုတင်သွင်းထားသော စစ်စတန် စနစ်တစ်ခုကို ကင်မရာ သုံးနေသော မီးအား ထိန်းချုပ်ခွင့်ပေးခြင်း"</string>
@@ -582,58 +582,58 @@
     <string name="permlab_brick" product="tv" msgid="4912674222121249410">"တီဗွီအား အပြီးပိတ်ရန်"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"ဖုန်းကို အမြဲတမ်း အလုပ်မလုပ်ရန်ပိတ်ခြင်း"</string>
     <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"appအား တက်ဘလက် တစ်ခုလုံးကို ထာဝရ ပိတ်ပစ်ခွင် ပြုသည်။ ၎င်းမှာ အထူး အန္တရာယ် ရှိနိုင်သည်။"</string>
-    <string name="permdesc_brick" product="tv" msgid="7070924544316356349">"တီဗွီတစ်ခုလုံးကို အမြဲပိတ်ပစ်ရန် app အား ခွင့်ပြုပါ။ ဤသည်မှာ လွန်စွာ အန္တရာယ်ရှိ၏။"</string>
+    <string name="permdesc_brick" product="tv" msgid="7070924544316356349">"တီဗွီတစ်ခုလုံးကို အမြဲပိတ်ပစ်ရန် app အား ခွင့်ပြုပါ။ ဤသည်မှာ လွန်စွာ အန္တရာယ်ရှိ၏။"</string>
     <string name="permdesc_brick" product="default" msgid="5788903297627283099">"appအား ဖုန်း တစ်ခုလုံးကို ထာဝရ ပိတ်ပစ်ခွင် ပြုသည်။ ၎င်းမှာ အထူး အန္တရာယ် ရှိနိုင်သည်။"</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"တက်ဘလက် မဖြစ်မနေပြန်လည်စတင်လုပ်ဆောင်ရန်"</string>
     <string name="permlab_reboot" product="tv" msgid="2112102119558886236">"တီဗွီအား မဖြစ်မနေ ပြန်လည်စတင်ရန်"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ဖုန်းကို မဖြစ်မနေပြန်လည်စတင်လုပ်ဆောင်ရန်"</string>
-    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"appအား တက်ဘလက်ကို ပြန်စတင်ရန် အတင်းအကြပ် ပြုလုပ်ခွင့် ပြုပါသည်။"</string>
-    <string name="permdesc_reboot" product="tv" msgid="7116222694344401650">"တီဗွီအား ပြန်လည်စတင်ခိုင်းရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"appအား ဖုန်းကို ပြန်စတင်ရန် အတင်းအကြပ် ပြုလုပ်ခွင့် ပြုပါသည်။"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"appအား တက်ဘလက်ကို ပြန်စတင်ရန် အတင်းအကြပ် ပြုလုပ်ခွင့် ပြုပါသည်။"</string>
+    <string name="permdesc_reboot" product="tv" msgid="7116222694344401650">"တီဗွီအား ပြန်လည်စတင်ခိုင်းရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"appအား ဖုန်းကို ပြန်စတင်ရန် အတင်းအကြပ် ပြုလုပ်ခွင့် ပြုပါသည်။"</string>
     <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USBသိုလှောင်ရာဖိုင်စနစ်အား အသုံးပြုခွင့်ပေးရန်"</string>
     <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SDကတ် ဖိုင် စနစ် အား အသုံးပြုခွင့်ပေးရန်"</string>
-    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်း၏ ဖိုင် စနစ်များကို တပ်ဆင်ခြင်း နှင့် ဖြုတ်ခြင်းကို ပြုလုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်း၏ ဖိုင် စနစ်များကို တပ်ဆင်ခြင်း နှင့် ဖြုတ်ခြင်းကို ပြုလုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USBသိုလှောင်ရာအား ဖျက်ရန်"</string>
     <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SDကတ်အား ဖျက်ရန်"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်းကို ပုံစံပြန်ချခွင့် ပြုသည်။"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"appအား ဖယ်ရှားရနိုင်သော သိုလှောင်ခန်းကို ပုံစံပြန်ချခွင့် ပြုသည်။"</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"စက်တွင်းသိုလှောင်ခြင်း၏အချက်အလက်ရယူရန်"</string>
-    <string name="permdesc_asec_access" msgid="3094563844593878548">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းထဲက အချက်အလက်များကို ရယူခွင့် ပြုသည်။"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းထဲက အချက်အလက်များကို ရယူခွင့် ပြုသည်။"</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"စက်တွင်းသိုလှောင်ခြင်း ပြုလုပ်ဖန်တီးရန်"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို ဖန်တီးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို ဖန်တီးခွင့် ပြုသည်။"</string>
     <string name="permlab_asec_destroy" msgid="526928328301618022">"စက်တွင်းသိုလှောင်ခြင်းအား ဖျက်စီးရန်"</string>
-    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို ဖျက်ပစ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို ဖျက်ပစ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"အတွင်းပိုင်း သိုလ​ှောင်ခန်းကို တပ်ဆင်/ဖြုတ်ခြင်း"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို တပ်ဆင်/ဖြုတ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို တပ်ဆင်/ဖြုတ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"စက်တွင်းသိုလှောင်မှုအားအမည်ပြောင်းခြင်း"</string>
-    <string name="permdesc_asec_rename" msgid="1794757588472127675">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို အမည်ပြောင်းခွင့် ပြုသည်။"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"appအား အတွင်းပိုင်း သိုလှောင်ခန်းကို အမည်ပြောင်းခွင့် ပြုသည်။"</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"တုန်ခုန်မှုအား ထိန်းချုပ်ခြင်း"</string>
-    <string name="permdesc_vibrate" msgid="6284989245902300945">"appအား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"appအား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"ဓါတ်မီးအား ထိန်းသိမ်းရန်"</string>
-    <string name="permdesc_flashlight" msgid="6522284794568368310">"appအား ကား ဖလက်ရှမီးကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
-    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB စက်ပစ္စည်းများအတွက် ကြိုက်နှစ်သက်ရာနှင့်ခွင့်ပြုချက်များကို စီမံရန်"</string>
-    <string name="permdesc_manageUsb" msgid="7776155430218239833">"appအား USB ကိရိယာများ၏ နှစ်ခြိုက်မှုများ နှင့် ခွင့်ပြုချက်များကို စီမံခန့်ခွဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"appအား ကား ဖလက်ရှမီးကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB စက်ပစ္စည်းများအတွက် ကြိုက်နှစ်သက်ရာနှင့်ခွင့်ပြုချက်များကို စီမံရန်"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"appအား USB ကိရိယာများ၏ နှစ်ခြိုက်မှုများ နှင့် ခွင့်ပြုချက်များကို စီမံခန့်ခွဲခွင့် ပြုသည်။"</string>
     <string name="permlab_accessMtp" msgid="4953468676795917042">"MTPပရိုတိုကောအား စတင်ရန်"</string>
-    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USBပရိုတိုကော အကောင်အထည်ဖော်ဆောင်ရွက်ရန် kernel MTPဒရိုင်ဘာအား သုံးစွဲခွင့်ပြုမည်။"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USBပရိုတိုကော အကောင်အထည်ဖော်ဆောင်ရွက်ရန် kernel MTPဒရိုင်ဘာအား သုံးစွဲခွင့်ပြုမည်။"</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"စက်ပစ္စည်းများကိုစမ်းသပ်ခြင်း"</string>
-    <string name="permdesc_hardware_test" msgid="6597964191208016605">"appအယဒ ဟာ့ဒ်ဝဲကို စမ်းသပ်ရန် ရည်ရွယ်ချက်ဖြင့် သာမည အစိတ်အပိုင်း အမျိုးမျိုးကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"appအယဒ ဟာ့ဒ်ဝဲကို စမ်းသပ်ရန် ရည်ရွယ်ချက်ဖြင့် သာမည အစိတ်အပိုင်း အမျိုးမျိုးကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_fm" msgid="8749504526866832">"FM ရေဒီယိုကို ရယူသုံးရန်"</string>
-    <string name="permdesc_fm" msgid="4145699441237962818">"appအား FM ရေဒီယို ဖွင့်လျက် နားထောင်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_fm" msgid="4145699441237962818">"appအား FM ရေဒီယို ဖွင့်လျက် နားထောင်ခွင့် ပြုသည်။"</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"ဖုန်းနံပါတ်များကိုတိုက်ရိုက်ခေါ်ဆိုခြင်း"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"အပလီကေးရှင်းအား အလိုအလျောက် ဖုန်းခေါ်ခွင့် ပြုပါ။ မလိုအပ်သော ဖုန်းခ များ ဖြစ်ပေါ်နိုင်ပါသည်။ ဒီခွင့်ပြုခြင်းမှာ အရေးပေါ်ဖုန်းခေါ်ခြင်း မပါဝင်ပါ။ သံသယဖြစ်စရာ အပလီကေးရှင်းများက သင့်မသိပဲ ဖုန်းခေါ်ခြင်းဖြင့် ဖုန်းခ ပိုမိုကျနိုင်ပါသည်။"</string>
-    <string name="permlab_callPrivileged" msgid="4198349211108497879">"မည်သည့်ဖုန်းနံပါတ်မဆိုအားတိုက်ရိုက်ခေါ်ဆိုခြင်း"</string>
-    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"appအား ဘယ် ဖုန်း နံပါတ်ကိုမဆို၊ အရေးပေါ် နံပါတ်များ အပါအဝင်ကို၊ သင်၏ စွက်ဖက်မှု မပါဘဲ၊ ခေါ်ဆိုခွင့် ပြုသည်။ အကြံအဖန် appများက အရေးပေါ် ဝန်ဆောင်မှုများ ထံသို့ မလိုလားအပ်သော သို့မဟုတ် တရားမဝင်သော ခေါ်ဆိုမှုများ ပြုလုပ်လာနိုင်ကြမည်။"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"မည်သည့်ဖုန်းနံပါတ်မဆိုအားတိုက်ရိုက်ခေါ်ဆိုခြင်း"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"appအား ဘယ် ဖုန်း နံပါတ်ကိုမဆို၊ အရေးပေါ် နံပါတ်များ အပါအဝင်ကို၊ သင်၏ စွက်ဖက်မှု မပါဘဲ၊ ခေါ်ဆိုခွင့် ပြုသည်။ အကြံအဖန် appများက အရေးပေါ် ဝန်ဆောင်မှုများ ထံသို့ မလိုလားအပ်သော သို့မဟုတ် တရားမဝင်သော ခေါ်ဆိုမှုများ ပြုလုပ်လာနိုင်ကြမည်။"</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMAတက်ပလက်အစသတ်မှတ်ခြင်းကို တိုက်ရိုက်စတင်ရန်"</string>
     <string name="permlab_performCdmaProvisioning" product="tv" msgid="3485391974208100809">"CDMA TV ပြင်ဆင်သတ်မှတ်မှုအား တိုက်ရိုက်စတင်ရန်"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMAဖုန်း အစသတ်မှတ်ခြင်းကို တိုက်ရိုက်စတင်ရန်"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"appအား CDMA အတွက် စီမံလုပ်ကိုင်မှုကို စတင်ခွင့် ပြုသည်။ ကြံဖန် appများက မလိုအပ်ဘဲနှင့် CDMA အတွက် စီမံလုပ်ကိုင်မှုကို စတင်နိုင်ကြသည်။"</string>
-    <string name="permlab_locationUpdates" msgid="7785408253364335740">"တည်နေရာအဆင့်မြှင့်ခြင်းသတိပေးချက်အားထိန်းချုပ်ရန်"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"appအား ရေဒီယိုထံမှ တည်နေရာ မွမ်းမံမှု အကြောင်းကြားစာများကို ပိတ်/ဖွင့်ခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်နိုင်ပါ။"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"appအား CDMA အတွက် စီမံလုပ်ကိုင်မှုကို စတင်ခွင့် ပြုသည်။ ကြံဖန် appများက မလိုအပ်ဘဲနှင့် CDMA အတွက် စီမံလုပ်ကိုင်မှုကို စတင်နိုင်ကြသည်။"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"တည်နေရာအဆင့်မြှင့်ခြင်းသတိပေးချက်အားထိန်းချုပ်ရန်"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"appအား ရေဒီယိုထံမှ တည်နေရာ မွမ်းမံမှု အကြောင်းကြားစာများကို ပိတ်/ဖွင့်ခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်နိုင်ပါ။"</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"ချက်ခ်အင်ဂုဏ်သတ္တိများအား ဝင်ရောက်ချိတ်ဆက်ခြင်း"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"appအား စစ်ဆေးရေး ဝန်ဆောင်မှုက အာပ်လုဒ် လုပ်ခဲ့သည့် အရည်အချင်းများကို ရယူသုံးလျက် ရေး/ဖတ် ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"appအား စစ်ဆေးရေး ဝန်ဆောင်မှုက အာပ်လုဒ် လုပ်ခဲ့သည့် အရည်အချင်းများကို ရယူသုံးလျက် ရေး/ဖတ် ခွင့် ပြုသည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"ဝဒ်ဂျက်အား ရွေးရန်"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"appအား မည်သည့် ဝီဂျက်ကို မည်သည့် app သုံးနိုင်ကြောင်းကို စနစ်များ ပြောခွင့် ပေးသည်။ ယင်း ခွင့်ပြုချက်မျိုး ရှိသော appသည် အခြား appများအား ကိုယ်ရေး ဒေတာများကို ရယူသုံးခွင့် ပေးနိုင်သည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"appအား မည်သည့် ဝီဂျက်ကို မည်သည့် app သုံးနိုင်ကြောင်းကို စနစ်များ ပြောခွင့် ပေးသည်။ ယင်း ခွင့်ပြုချက်မျိုး ရှိသော appသည် အခြား appများအား ကိုယ်ရေး ဒေတာများကို ရယူသုံးခွင့် ပေးနိုင်သည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ဖုန်းအခြေအနေအား မွမ်းမံခြင်း"</string>
-    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"appအား ဖုန်း၏ အင်္ဂါရပ်များကို ထိန်းချုပ်ခွင့် ပြုသည်။ ယင်း ခွင့်ပြုချက် ရှိသော appသည် ကွန်ရက်များကို ပြောင်းလဲခြင်း၊ ဖုန်း ရေဒီယိုကို ပိတ်ဖွင့်ခြင်း နှင့် အလားတူများကို သင့်ကို အကြောင်းတောင် မကြားဘဲ ပြုလုပ်နိုင်သည်။"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"appအား ဖုန်း၏ အင်္ဂါရပ်များကို ထိန်းချုပ်ခွင့် ပြုသည်။ ယင်း ခွင့်ပြုချက် ရှိသော appသည် ကွန်ရက်များကို ပြောင်းလဲခြင်း၊ ဖုန်း ရေဒီယိုကို ပိတ်ဖွင့်ခြင်း နှင့် အလားတူများကို သင့်ကို အကြောင်းတောင် မကြားဘဲ ပြုလုပ်နိုင်သည်။"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ဖုန်းရဲ့ အခြေအနေ နှင့် အမှတ်သညာအား ဖတ်ခြင်း"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"အပလီကေးရှင်းအား ဖုန်းရဲ့ စွမ်းဆောင်ချက်များအား သုံးခွင့်ပြုပါ။ အပလီကေးရှင်းအနေဖြင့် ဖုန်းနံပါတ်၊ စက်နံပါတ်၊ ဖုန်းခေါ်နေမှု ရှိမရှိနှင့် တဖက်မှ ဖုန်းနံပါတ် များအား သိရှိနိုင်ပါသည်"</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ဖုန်းရဲ့ တိကျသော အခြေအနေအား ဖတ်ရှုခြင်း"</string>
@@ -641,99 +641,99 @@
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"တက်ပလက်အား ပိတ်ခြင်းမှ ကာကွယ်ခြင်း"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"တီဗွီအား နားနေခြင်းမှ ကာကွယ်ရန်"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ဖုန်းအနားယူခြင်းမပြုလုပ်စေရန်"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"appအား တက်ဘလက်ကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။"</string>
-    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"တီဗွီ ရပ်နားသွားခြင်းအား ကာကွယ်ရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"appအား ဖုန်းကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"appအား တက်ဘလက်ကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။"</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"တီဗွီ ရပ်နားသွားခြင်းအား ကာကွယ်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"appအား ဖုန်းကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။"</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"အနီအောက်ရောင်ခြည် ထုတ်လွှတ်ခြင်း"</string>
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"အပလီကေးရှင်းအား တက်ဘလက်ရဲ့ အနီအောက်ရောင်ခြည် ထုတ်လွှတ်ခြင်းအား သုံးခွင့်ပေးခြင်း"</string>
-    <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"တီဗွီ၏ အင်ဖရာရက် ထုတ်လွှတ်မှုအား အသုံးပြုရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"တီဗွီ၏ အင်ဖရာရက် ထုတ်လွှတ်မှုအား အသုံးပြုရန် app အား ခွင့်ပြုပါ။"</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"အပလီကေးရှင်းအား ဖုန်းရဲ့ အနီအောက်ရောင်ခြည် ထုတ်လွှတ်ခြင်းအား သုံးခွင့်ပေးခြင်း"</string>
-    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"တက်ဘလက် အဖွင့်အပိတ်"</string>
-    <string name="permlab_devicePower" product="tv" msgid="7579718349658943416">"တီဗွီ ပါဝါ ဖွင့်ရန် သို့ ပိတ်ရန်"</string>
-    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ဖုန်းဖွင့် (သို့)ပိတ်"</string>
-    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"appအား တက်ဘလက်ကို ဖွင့် သို့မဟုတ် ပိတ်ခွင့် ပြုသည်။"</string>
-    <string name="permdesc_devicePower" product="tv" msgid="1334908641773273512">"တီဗွီအား ဖွင့်ရန် သို့မဟုတ် ပိတ်ရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"appအား ဖုန်းကို ဖွင့် သို့မဟုတ် ပိတ်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"တက်ဘလက် အဖွင့်အပိတ်"</string>
+    <string name="permlab_devicePower" product="tv" msgid="7579718349658943416">"တီဗွီ ပါဝါ ဖွင့်ရန် သို့ ပိတ်ရန်"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ဖုန်းဖွင့် (သို့)ပိတ်"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"appအား တက်ဘလက်ကို ဖွင့် သို့မဟုတ် ပိတ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_devicePower" product="tv" msgid="1334908641773273512">"တီဗွီအား ဖွင့်ရန် သို့မဟုတ် ပိတ်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"appအား ဖုန်းကို ဖွင့် သို့မဟုတ် ပိတ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_userActivity" msgid="1677844893921729548">"မျက်နှာပြင်မှိန်ချိန် ပြန်ညှိရန်"</string>
     <string name="permdesc_userActivity" msgid="651746160252248024">"မျက်နှာပြင်မှိန်ချိန် ပြန်ညှိရန် app ကိုခွင့်ပြုပါ။"</string>
-    <string name="permlab_factoryTest" msgid="3715225492696416187">"စက်ရုံစမ်းသပ်စနစ်ဖြင့် အလုပ်လုပ်ဆောင်စေရန်"</string>
-    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ထုတ်လုပ်သူ၏အနိမ့်စားအဆင့်စမ်းသပ်မှုအနေဖြင့်လုပ်ဆောင်စေမည် တက်ပလက်စက်အား လုံးဝဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုမည်။ တက်ပလက်မှာ ထုတ်လုပ်သူ၏စမ်းသပ်မှုစနစ်ဖြင့် လုပ်ဆောင်နေစဥ်သာ ရရှိမည်။"</string>
-    <string name="permdesc_factoryTest" product="tv" msgid="2105643629211155695">"တီဗွီ၏ ဟာ့ဒ်ဝဲစက်ပိုင်းဆိုင်ရာသို့ အပြည့်အစုံဝင်ခွင့်ပြုရင်း၊ အဆင့်နိမ့်ထုတ်လုပ်သူ၏ စမ်းသပ်မှုအား လုပ်ဆောင်ပါ။ တီဗွီအား ထုတ်လုပ်သူ၏ စမ်းသပ်မုဒ်တွင် ဖွင့်ထားစဉ်တွင်သာ လုပ်ဆောင်နိုင်မည်။"</string>
-    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ထုတ်လုပ်သူ၏အနိမ့်စားအဆင့်စမ်းသပ်မှုအနေဖြင့်လုပ်ဆောင်စေမည် ဖုန်းစက်အား လုံးဝဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုမည် ဖုန်းမှာ ထုတ်လုပ်သူ၏စမ်းသပ်မှုစနစ်ဖြင့် လုပ်ဆောင်နေစဥ်သာ ရရှိမည်"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"စက်ရုံစမ်းသပ်စနစ်ဖြင့် အလုပ်လုပ်ဆောင်စေရန်"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ထုတ်လုပ်သူ၏အနိမ့်စားအဆင့်စမ်းသပ်မှုအနေဖြင့်လုပ်ဆောင်စေမည် တက်ပလက်စက်အား လုံးဝဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုမည်။ တက်ပလက်မှာ ထုတ်လုပ်သူ၏စမ်းသပ်မှုစနစ်ဖြင့် လုပ်ဆောင်နေစဥ်သာ ရရှိမည်။"</string>
+    <string name="permdesc_factoryTest" product="tv" msgid="2105643629211155695">"တီဗွီ၏ ဟာ့ဒ်ဝဲစက်ပိုင်းဆိုင်ရာသို့ အပြည့်အစုံဝင်ခွင့်ပြုရင်း၊ အဆင့်နိမ့်ထုတ်လုပ်သူ၏ စမ်းသပ်မှုအား လုပ်ဆောင်ပါ။ တီဗွီအား ထုတ်လုပ်သူ၏ စမ်းသပ်မုဒ်တွင် ဖွင့်ထားစဉ်တွင်သာ လုပ်ဆောင်နိုင်မည်။"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ထုတ်လုပ်သူ၏အနိမ့်စားအဆင့်စမ်းသပ်မှုအနေဖြင့်လုပ်ဆောင်စေမည် ဖုန်းစက်အား လုံးဝဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုမည် ဖုန်းမှာ ထုတ်လုပ်သူ၏စမ်းသပ်မှုစနစ်ဖြင့် လုပ်ဆောင်နေစဥ်သာ ရရှိမည်"</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"နောက်ခံအား သတ်မှတ်ရန်"</string>
-    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"appအား စနစ် နောက်ခံပုံကို သတ်မှတ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"appအား စနစ် နောက်ခံပုံကို သတ်မှတ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"နောက်ခံပုံအား အရွယ်အစားပြောင်းရန်"</string>
-    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"appအား စနစ် နောက်ခံပုံ ဆိုက်ဆိုင်ရာ ညွှန်းချက်များကို သတ်မှတ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"appအား စနစ် နောက်ခံပုံ ဆိုက်ဆိုင်ရာ ညွှန်းချက်များကို သတ်မှတ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"စနစ်အား မူလစက်ရုံအခြအေနေထံ ပြန်လည်သတ်မှတ်ရန်"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"appအား စနစ်ကို စက်ရုံအတိုင်း လုံးဝ ပြန်ညှိခြင်း၊ ဒေတာများ၊ စီစင်ဖွဲ့စည်းမှု နှင့် တပ်ဆင်ပြီး appများ အားလုံးကို ဖျက်ပစ်ခြင်း လုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"appအား စနစ်ကို စက်ရုံအတိုင်း လုံးဝ ပြန်ညှိခြင်း၊ ဒေတာများ၊ စီစင်ဖွဲ့စည်းမှု နှင့် တပ်ဆင်ပြီး appများ အားလုံးကို ဖျက်ပစ်ခြင်း လုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"အချိန်သတ်မှတ်ရန်"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"appအား တက်ဘလက်၏ နာရီ အချိန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
-    <string name="permdesc_setTime" product="tv" msgid="1826398919861882682">"တီဗွီ၏ အချိန်နာရီအား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"appအား ဖုန်း၏ နာရီ အချိန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"appအား တက်ဘလက်၏ နာရီ အချိန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_setTime" product="tv" msgid="1826398919861882682">"တီဗွီ၏ အချိန်နာရီအား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"appအား ဖုန်း၏ နာရီ အချိန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"အချိန်ဇုန်းအား သတ်မှတ်ခြင်း"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"appအား တက်ဘလက်၏ နာရီ ဇုန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
-    <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"တီဗွီ၏ အချိန်အပိုင်းအခြားဇုန်အား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"appအား ဖုန်း၏ နာရီ ဇုန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
-    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerServiceအနေဖြင့်ပြုမူရန်"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"appအား တက်ဘလက်၏ နာရီ ဇုန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"တီဗွီ၏ အချိန်အပိုင်းအခြားဇုန်အား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"appအား ဖုန်း၏ နာရီ ဇုန်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerServiceအနေဖြင့်ပြုမူရန်"</string>
     <string name="permdesc_accountManagerService" msgid="1948455552333615954">"အပလီကေးရှင်းအား အကောင့် စစ်ဆေးသော အရာများအား ဖုန်းခေါ်ခွင့်ပြုပါ"</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"စက်ပေါ်မှာ အကောင့်များ ရှာဖွေခြင်း"</string>
     <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"အပလီကေးရှင်းအား တက်ဘလက်မှ သိရှိထားသော အကောင့်များအား ရယူခွင့်ပေးပါ။ ဒီထဲတွင် သင် ထည့်သွင်းထားသော အပလီကေးရှင်းများမှတဆင့် ပြုလုပ်ထားသော အကောင့်များပါ ပါဝင်နိုင်ပါသည်။"</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"တီဗွီ သိသော အကောင့်စာရင်းအား ရယူခွင့်ကို app အား ခွင့်ပြုပါ။ သင်ထည့်သွင်းထားသည့် အပလီကေးရှင်းများမှ ဖန်တီးထားသော မည်သည့်အကောင့်မဆို ပါဝင်မည်။"</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"တီဗွီ သိသော အကောင့်စာရင်းအား ရယူခွင့်ကို app အား ခွင့်ပြုပါ။ သင်ထည့်သွင်းထားသည့် အပလီကေးရှင်းများမှ ဖန်တီးထားသော မည်သည့်အကောင့်မဆို ပါဝင်မည်။"</string>
     <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"အပလီကေးရှင်းအား ဖုန်းမှ သိရှိထားသော အကောင့်စာရင်းများအား ရယူခွင့်ပေးပါ။ ဒီထဲတွင် သင် ထည့်သွင်းထားသော အပလီကေးရှင်းများမှတဆင့် ပြုလုပ်ထားသော အကောင့်များပါ ပါဝင်နိုင်ပါသည်။"</string>
     <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"အကောင့်များ ဖန်တီးရန်နှင့် စကားဝှက်များ ရွေးချယ်ရန်"</string>
-    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"appအား အကောင့် မန်နေဂျာ၏ အကောင့် စိစစ်ရေး လုပ်နိုင်စွမ်းများကို၊ အကောင့်များ ဖန်တီးခြင်း နှင့် ၎င်းတို့၏ စကားဝှက်များကို ရယူခြင်း နှင့် သတ်မှတ်ခြင်း အပါအဝင်ကို၊ အသုံးချခွင့် ပြုသည်။"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"appအား အကောင့် မန်နေဂျာ၏ အကောင့် စိစစ်ရေး လုပ်နိုင်စွမ်းများကို၊ အကောင့်များ ဖန်တီးခြင်း နှင့် ၎င်းတို့၏ စကားဝှက်များကို ရယူခြင်း နှင့် သတ်မှတ်ခြင်း အပါအဝင်ကို၊ အသုံးချခွင့် ပြုသည်။"</string>
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"အကောင့်များအား ထည့် သို့ ထုတ်ပါ"</string>
-    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"appအား အကောင့်များ ထည့်ခြင်း နှင့် ဖယ်ရှားခြင်း နှင့် ၎င်းတို့၏ စကားဝှက်များကို ဖျက်ခြင်းလို လုပ်ရပ်များကို လုပ်ကိုင်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"appအား အကောင့်များ ထည့်ခြင်း နှင့် ဖယ်ရှားခြင်း နှင့် ၎င်းတို့၏ စကားဝှက်များကို ဖျက်ခြင်းလို လုပ်ရပ်များကို လုပ်ကိုင်ခွင့် ပြုသည်။"</string>
     <string name="permlab_useCredentials" msgid="235481396163877642">"စက်ပေါ်ရှိ သုံးစွဲသူအကောင့်များ"</string>
-    <string name="permdesc_useCredentials" msgid="7984227147403346422">"appအား အထောက်အထား စိစစ်ရေး တိုကင်များကို တောင်းဆိုခွင့် ပြုသည်။"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"appအား အထောက်အထား စိစစ်ရေး တိုကင်များကို တောင်းဆိုခွင့် ပြုသည်။"</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ကွန်ရက် ချိတ်ဆက်မှုများအား ကြည့်ရန်"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"အပလီကေးရှင်းအား မည်သည့်ကွန်ရက်နက်ဝဘ်ရှိသလဲ၊ မည်သည့်ကွန်ရက်နှင့် ချိတ်ဆက်ထားလဲ စသည်ဖြင့် ကွန်ရက်ချိတ်ဆက်မှုများ၏ သတင်းအချက်အလက်များကို ကြည့်ခွင့်ပေးရန်"</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"အပြည့်အ၀ ကွန်ရက်သုံးခွင့်ရရန်"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"အပလီကေးရှင်းအား ကွန်ရက်ဆော့ကတ်များ တည်ဆောက်ခွင့်၊ တသီးတသန့် ကွန်ရက် ပရိုတိုကောလ်များ သုံးခွင့် ပြုပါ။ အင်တာနက်မှ အချက်အလက်များ ပေးပို့ခြင်းကို ဘရောက်ဇာနှင့် တခြား အပလီကေးရှင်းများက လုပ်ဆောင်ပေးသောကြောင့် ဒီခွင့်ပြုချက်က အင်တာနက်မှ အချက်အလက် ပေးပို့ခြင်း မလိုအပ်ပါ"</string>
-    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ကွန်ယက်အပြင်အဆင်နှင့် အသွားအလာများကို ပြောင်းလဲ/ကြားဖြတ်စေခြင်း"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"appအား ကွန်ရက် ဆက်တင်များကို ပြောင်းလဲလျက် ကွန်ရက် ဆက်သွယ်မှုများ အားလုံးကို ကြားဖြတ်ယူခြင်း နှင့် စုံစမ်းစစ်ဆေးခြင်း၊ ဥပမာ၊ မည်သည့် APN ၏ ပရော့က်စီ နှင့် ပို့တ်များကို ပြောင်းလဲခြင်း၊ ပြုလုပ်ခွင့် ပြုသည်။ ကြံဖန် appများက သင် မသိရဘဲနှင့် ကွန်ရက် အထုပ်များကို စောင့်ကြည့်ခြင်း၊ အခြားသို့ ညွှန်းပို့ခြင်း၊ သို့မဟုတ် မွမ်းမံခြင်းကို ပြုလုပ်နိုင်သည်။"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ကွန်ယက်အပြင်အဆင်နှင့် အသွားအလာများကို ပြောင်းလဲ/ကြားဖြတ်စေခြင်း"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"appအား ကွန်ရက် ဆက်တင်များကို ပြောင်းလဲလျက် ကွန်ရက် ဆက်သွယ်မှုများ အားလုံးကို ကြားဖြတ်ယူခြင်း နှင့် စုံစမ်းစစ်ဆေးခြင်း၊ ဥပမာ၊ မည်သည့် APN ၏ ပရော့က်စီ နှင့် ပို့တ်များကို ပြောင်းလဲခြင်း၊ ပြုလုပ်ခွင့် ပြုသည်။ ကြံဖန် appများက သင် မသိရဘဲနှင့် ကွန်ရက် အထုပ်များကို စောင့်ကြည့်ခြင်း၊ အခြားသို့ ညွှန်းပို့ခြင်း၊ သို့မဟုတ် မွမ်းမံခြင်းကို ပြုလုပ်နိုင်သည်။"</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"ကွန်ယက်ဆက်သွယ်မှုအားပြောင်းခြင်း"</string>
-    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"appအား ကွန်ရက် ချိတ်ဆက်နိုင်စွမ်း အခြေအနေကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
-    <string name="permlab_changeTetherState" msgid="5952584964373017960">"တစ်ဆင့်ပွါးဆက်သွယ်မှုအားပြောင်းခြင်း"</string>
-    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"appအား ချိတ်တွဲထားသည့် ကွန်ရက် ချိတ်ဆက်နိုင်စွမ်း အခြေအနေကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"appအား ကွန်ရက် ချိတ်ဆက်နိုင်စွမ်း အခြေအနေကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"တစ်ဆင့်ပွါးဆက်သွယ်မှုအားပြောင်းခြင်း"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"appအား ချိတ်တွဲထားသည့် ကွန်ရက် ချိတ်ဆက်နိုင်စွမ်း အခြေအနေကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"နောက်ခံဒေတာအသုံးပြုခြင်းဆက်တင်အား ပြောင်းခြင်း"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"appအား နောက်ခံ ဒေတာ သုံးစွဲမှု ဆက်တင်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"appအား နောက်ခံ ဒေတာ သုံးစွဲမှု ဆက်တင်ကို ပြောင်းလဲခွင့် ပြုသည်။"</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"ဝိုင်ဖိုင် ချိတ်ဆက်မှများအား ကြည့်ရန်"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"အပလီကေးရှင်းအား ဝိုင်ဖိုင် ဖွင့်ထား မထား၊ ချိတ်ဆက်ထားသော ပိုင်ဖိုင် စက်ပစ္စည်း စသဖြင့် ဝိုင်ဖိုင်နှင့် သက်ဆိုင်သော အချက်အလက် ကြည့်ခွင့်ပေးရန်"</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"ဝိုင်ဖိုင်အား ချိတ်ဆက်ရန် နှင့် ဆက်သွယ်မှု ဖြတ်တောက်ရန်"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"အပလီကေးရှင်းအား ဝိုင်ဖိုင်တည်နေရာများအား ဆက်သွယ်ခြင်း၊ ဆက်သွယ်မှု ရပ်ဆိုင်းခြင်း၊ ဝိုင်ဖိုင်ကွန်ရက်အတွက် စက်အပြင်အဆင်များ ပြုလုပ်ခြင်း ခွင့်ပြုပါ"</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicastလက်ခံခြင်းကိုခွင့်ပြုရန်"</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicastလက်ခံခြင်းကိုခွင့်ပြုရန်"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"အပလီကေးရှင်းအား ဝိုင်ဖိုင်ကွန်ရက်ပေါ်တွင် သင့်တက်ဘလက်တစ်ခုထဲအားမဟုတ်ပဲ multicast လိပ်စာအား သုံးပြီး လွှင့်ထုတ်သော အချက်အလက်များ လက်ခံခွင့် ပြုပါ။ ဒီလိုသုံးခြင်းမှာ  non-multicast ထက် ဘက်ထရီ ပိုကုန်ပါသည်။"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"သင့် တီဗွီနှင့်သာ မဟုတ်ဘဲ၊ ကွန်ယက်လိပ်စာများစွာ သုံးသော ဝိုင်ဖိုင်ကွန်ယက်ရှိ စက်ကိရိယာအားလုံးသို့ ပို့သော ပက်ကက်များအား လက်ခံရရှိရန် app အားခွင့်ပြုပါ။ ၎င်းသည် ကွန်ယက်လိပ်စာများစွာမသုံးသောမုဒ်ထက် စွမ်းအားပိုသုံး၏။"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"သင့် တီဗွီနှင့်သာ မဟုတ်ဘဲ၊ ကွန်ယက်လိပ်စာများစွာ သုံးသော ဝိုင်ဖိုင်ကွန်ယက်ရှိ စက်ကိရိယာအားလုံးသို့ ပို့သော ပက်ကက်များအား လက်ခံရရှိရန် app အားခွင့်ပြုပါ။ ၎င်းသည် ကွန်ယက်လိပ်စာများစွာမသုံးသောမုဒ်ထက် စွမ်းအားပိုသုံး၏။"</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"အပလီကေးရှင်းအား ဝိုင်ဖိုင်နက်ဘ်ပေါ်တွင် သင့်ဖုန်းတစ်ခုထဲအားမဟုတ်ပဲ multicast လိပ်စာအား သုံးပြီး လွှင့်ထုတ်သော အချက်အလက်များ လက်ခံခွင့် ပြုပါ။ ဒီလိုသုံးခြင်းမှာ non-multicast ထက် ဘက်ထရီ ပိုကုန်ပါသည်။"</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ဘလူးတု ဆက်တင်များအား သုံးခွင့်ပေးရန်"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"appအား ဒေသန္တရ ဘလူးတုသ် တက်ဘလက်ကို စီစဉ်ဖွဲ့စည်းခွင့်ကို၎င်း၊ အဝေးထိန်း ကိရိယာများကို ရှာကြံလျက် ချိတ်တွဲခွင့်ကို၎င်း ပေးထားသည်။"</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ကွန်ယက်တွင်းရှိ ဘလူးတုသ် တီဗွီအား ပုံစံပြင်ရန်နှင့်၊ အဝေးရှိ စက်ကိရိယာများအား ရှာဖွေတွဲဖက်ရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"appအား ဒေသန္တရ ဘလူးတုသ် ဖုန်းကို စီစဉ်ဖွဲ့စည်းခွင့်ကို၎င်း၊ အဝေးထိန်း ကိရိယာများကို ရှာကြံလျက် ချိတ်တွဲခွင့်ကို၎င်း ပေးထားသည်။"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"appအား ဒေသန္တရ ဘလူးတုသ် တက်ဘလက်ကို စီစဉ်ဖွဲ့စည်းခွင့်ကို၎င်း၊ အဝေးထိန်း ကိရိယာများကို ရှာကြံလျက် ချိတ်တွဲခွင့်ကို၎င်း ပေးထားသည်။"</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ကွန်ယက်တွင်းရှိ ဘလူးတုသ် တီဗွီအား ပုံစံပြင်ရန်နှင့်၊ အဝေးရှိ စက်ကိရိယာများအား ရှာဖွေတွဲဖက်ရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"appအား ဒေသန္တရ ဘလူးတုသ် ဖုန်းကို စီစဉ်ဖွဲ့စည်းခွင့်ကို၎င်း၊ အဝေးထိန်း ကိရိယာများကို ရှာကြံလျက် ချိတ်တွဲခွင့်ကို၎င်း ပေးထားသည်။"</string>
     <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"အပလီကေးရှင်းသုံးပြီး ဘလူးတုသ်နှင့် ပူးတွဲချိတ်ဆက်ခြင်း အား ခွင့်ပြုရန်"</string>
     <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"အပလီကေးရှင်းကို အဝေးက စက်များနဲ့ ကိုင်ထားသူ မလုပ်ဆောင်ပဲ ပူးတွဲခွင့်ပေးခြင်း"</string>
     <string name="permdesc_bluetoothPriv" product="tv" msgid="8045735193417468857">"အပလီကေးရှင်းကို အဝေးက စက်များနဲ့ ကိုင်ထားသူ မလုပ်ဆောင်ပဲ ပူးတွဲခွင့်ပေးခြင်း"</string>
     <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"အပလီကေးရှင်းကို အဝေးက စက်များနဲ့ ကိုင်ထားသူ မလုပ်ဆောင်ပဲ ပူးတွဲခွင့်ပေးခြင်း"</string>
     <string name="permlab_bluetoothMap" msgid="6372198338939197349">"ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးရန်"</string>
-    <string name="permdesc_bluetoothMap" product="tablet" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
-    <string name="permdesc_bluetoothMap" product="tv" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
-    <string name="permdesc_bluetoothMap" product="default" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_bluetoothMap" product="tablet" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_bluetoothMap" product="tv" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_bluetoothMap" product="default" msgid="5784090105926959958">"appအား ဘလူးတုသ် MAP ဒေတာကို ရယူသုံးခွင့် ပြုသည်။"</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"ဝိုင်မက်စ် နှင့် ချိတ်ဆက်ရန်နှင့် ဆက်သွယ်မှု ဖြတ်တောက်ရန်"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"အပလီကေးရှင်းအား ဝိုင်မက်စ် အခြေအနေ ကြည့်ခွင့်ပေးရန် ဥပမာ ဝိုင်မက်စ် ဖွင့်ထား မထား၊ ဝိုင်မက်စ် ချိတ်ဆက်ထားသော ကွန်ရက်အခြေအနေ"</string>
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"ဝိုက်မက်စ် အခြေအနေအား ပြင်ရန်"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"အပလီကေးရှင်းအား တက်ဘလက်ကို ဝိုင်မက်စ် ကွန်ရက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်မှု ရပ်ဆိုင်းခြင်းများ လုပ်ခွင့်ပြုပါ"</string>
-    <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"တီဗွီနှင့် ချိတ်ဆက်ရန် app အား ခွင့်ပြုပြီး တီဗွီနှင့် WiMAX ကွန်ယက်များ ချိတ်ဆက်ထားမှုအား ဖြတ်တောက်ပါ။"</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"တီဗွီနှင့် ချိတ်ဆက်ရန် app အား ခွင့်ပြုပြီး တီဗွီနှင့် WiMAX ကွန်ယက်များ ချိတ်ဆက်ထားမှုအား ဖြတ်တောက်ပါ။"</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"အပလီကေးရှင်းအား ဖုန်းကို ဝိုင်မက်စ် ကွန်ရက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်မှု ရပ်ဆိုင်းခြင်းများ လုပ်ခွင့်ပြုပါ"</string>
     <string name="permlab_scoreNetworks" msgid="6445777779383587181">"ကွန်ရက်များကို အမှတ်ပေးခြင်း"</string>
-    <string name="permdesc_scoreNetworks" product="tablet" msgid="1304304745850215556">"appအား ကွန်ရက်များကို အဆင့်အတန်း သတ်မှတ်ခွင့် ပြုကာ တက်ဘလက် အနေနှင့် မည်သည့် ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်းကို ဆုံးဖြတ်စေနိုင်သည်။"</string>
-    <string name="permdesc_scoreNetworks" product="tv" msgid="5444434643862417649">"ကွန်ယက်များအား အဆင့်အတန်း သတ်မှတ်ပြီး တီဗွီသည် မည်သည့်ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်း အားသာပေးစေရန် app အား ခွင့်ပြုပါ။"</string>
-    <string name="permdesc_scoreNetworks" product="default" msgid="1831501848178651379">"appအား ကွန်ရက်များကို အဆင့်အတန်း သတ်မှတ်ခွင့် ပြုကာ ဖုန်း အနေနှင့် မည်သည့် ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်းကို ဆုံးဖြတ်စေနိုင်သည်။"</string>
+    <string name="permdesc_scoreNetworks" product="tablet" msgid="1304304745850215556">"appအား ကွန်ရက်များကို အဆင့်အတန်း သတ်မှတ်ခွင့် ပြုကာ တက်ဘလက် အနေနှင့် မည်သည့် ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်းကို ဆုံးဖြတ်စေနိုင်သည်။"</string>
+    <string name="permdesc_scoreNetworks" product="tv" msgid="5444434643862417649">"ကွန်ယက်များအား အဆင့်အတန်း သတ်မှတ်ပြီး တီဗွီသည် မည်သည့်ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်း အားသာပေးစေရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_scoreNetworks" product="default" msgid="1831501848178651379">"appအား ကွန်ရက်များကို အဆင့်အတန်း သတ်မှတ်ခွင့် ပြုကာ ဖုန်း အနေနှင့် မည်သည့် ကွန်ရက်ကို ပိုနှစ်ခြိုက်သင့်ကြောင်းကို ဆုံးဖြတ်စေနိုင်သည်။"</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"ဘလူးတု စက်များနှင့် အတူတွဲချိတ်ရန်"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"အပလီကေးရှင်းအား တက်ဘလက်ပေါ်မှ ဘလူးတုသ် အပြင်အဆင်အား ကြည့်ခွင့်၊ တခြားစက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်ခြင်းကို လက်ခံခွင့်ပြုပါ။"</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"တီဗွီတွင် ဘလူးတုသ်အတွက် ပုံစံပြင်ခြင်းများ ဝင်ကြည့်ရန်နှင့်၊ တွဲဖက်ထားသည့် စက်ကိရိယာများအား ချိတ်ဆက်မှုပြုရန်နှင့်လက်ခံရန် app အား ခွင့်ပြုပါ။"</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"တီဗွီတွင် ဘလူးတုသ်အတွက် ပုံစံပြင်ခြင်းများ ဝင်ကြည့်ရန်နှင့်၊ တွဲဖက်ထားသည့် စက်ကိရိယာများအား ချိတ်ဆက်မှုပြုရန်နှင့်လက်ခံရန် app အား ခွင့်ပြုပါ။"</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"အပလီကေးရှင်းအား ဖုန်းမှဘလူးတု အပြင်အဆင်အား ကြည့်ခွင့်၊ တခြားစက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်ခြင်းကို လက်ခံခွင့်ပြုပါ။"</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"appအား တာတို စက်ကွင်း ဆက်သွယ်ရေး (NFC) တဲဂ်များ၊ ကဒ်များ နှင့် ဖတ်ကြသူတို့နှင့် ဆက်သွယ်ပြောဆိုခွင့် ပြုသည်။"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"appအား တာတို စက်ကွင်း ဆက်သွယ်ရေး (NFC) တဲဂ်များ၊ ကဒ်များ နှင့် ဖတ်ကြသူတို့နှင့် ဆက်သွယ်ပြောဆိုခွင့် ပြုသည်။"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ဖန်သားပြင် သော့ချခြင်းအား မလုပ်နိုင်အောင် ပိတ်ရန်"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"အပလီကေးရှင်းအား သော့ချခြင်းနှင့် သက်ဆိုင်ရာ စကားဝှက်သတ်မှတ်ခြင်းများအား မသုံးနိုင်အောင် ပိတ်ခြင်းကို ခွင့်ပြုရန်။ ဥပမာ ဖုန်းလာလျှင် သော့ပိတ်ခြင်း ပယ်ဖျက်ခြင်း၊ ဖုန်းပြောပြီးလျှင် သော့ကို အလိုအလျောက် ပြန်ပိတ်ခြင်း"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ထပ်တူပြုအဆင်အပြင်အားဖတ်ခြင်း"</string>
@@ -742,48 +742,48 @@
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"အကောင့်တစ်ခုအတွက် ထပ်တူညီအောင်လုပ်သော ဆက်တင်များကို ပြင်ရန် အပလီကေးရှင်းကို ခွင့်ပြုရန်။ ဥပမာ People အပလီကေးရှင်း က အကောင့်တစ်ခုနှင့် ထပ်တူညီအောင် လုပ်ဆောင်ခြင်းအား ဖွင့်ရန် သုံးနိုင်သည်။"</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"ထပ်တူကူးခြင်း ကိန်းဂဏန်းအချက်အလက်များကို ဖတ်ခြင်း"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"အပလီကေးရှင်းအား အကောင့်တစ်ခု၏ ထပ်တူညီအောင် လုပ်ဆောင်မှု အခြေအနေ (ပြီးခဲ့သော အဖြစ်အပျက်၊ ဒေတာ ပမာဏ ပါဝင်မှု များအပါအဝင်)ကို ဖတ်ရှုခွင့် ပြုပါ။"</string>
-    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"အမည်သွင်းထားသောဖိဖ့်များကို ဖတ်ခြင်း"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"appအား လောလောဆယ် စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများ ဆိုင်ရာ အသေးစိတ်များကို ရယူခွင့်ပြုသည်။"</string>
-    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"အမည်သွင်းထားသောဖိဖ့်များကို ရေးခြင်း"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"appအား လောလောဆယ် စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများကို ပြောင်းပစ်နိုင်သည်။"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"အမည်သွင်းထားသောဖိဖ့်များကို ဖတ်ခြင်း"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"appအား လောလောဆယ် စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများ ဆိုင်ရာ အသေးစိတ်များကို ရယူခွင့်ပြုသည်။"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"အမည်သွင်းထားသောဖိဖ့်များကို ရေးခြင်း"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"appအား လောလောဆယ် စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက သင်၏ စင့်က် လုပ်ပြီးသား ထည့်သွင်းမှုများကို ပြောင်းပစ်နိုင်သည်။"</string>
     <string name="permlab_readDictionary" msgid="4107101525746035718">"အဘိဓာန်သို့ သင့် ထည့်ထားသည်များအား ဖတ်ခြင်း"</string>
     <string name="permdesc_readDictionary" msgid="659614600338904243">"အပလီကေးရှင်းအား အဘိဓာန်တွင် သိမ်းဆည်းထားသော စာလုံးအားလုံး၊ နာမည်များနှင့် စာစုများ ဖတ်ရှုခွင့် ပြုရန်"</string>
     <string name="permlab_writeDictionary" msgid="2183110402314441106">"သုံးစွဲသူ၏ အဘိဓာန် ထဲသို့ စာလုံးများ ထည့်ခြင်း"</string>
-    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"အသုံးပြုသူ အဘိဓာန်ထဲသို့ စာလုံး အသစ်များကို ရေးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"အသုံးပြုသူ အဘိဓာန်ထဲသို့ စာလုံး အသစ်များကို ရေးခွင့် ပြုသည်။"</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB သိုလှောင်မှုမှ အချက်အလက်များအား ဖတ်ခြင်း"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD ကဒ်မှ အချက်အလက်များအား ဖတ်ခြင်း"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"အပလီကေးရှင်းအား USB သိုလှောင်မှုပေါ်မှ ဒေတာများ ဖတ်ရှုခွင့်ပြုခြင်း"</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"အပလီကေးရှင်းအား အက်စ်ဒီ ကဒ်ပေါ်မှ ဒေတာများ ဖတ်ရှုခွင့်ပြုခြင်း"</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USBမှဒေတာအား ပြင် သို့ ဖျက်ရန်"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD ကဒ်ပေါ်မှ အချက်အလက်များအား ပြင်ဆင်ခြင်း သို့ ဖျက်ပစ်ခြင်း"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"appအား USB သိုလှောင်ခန်းသို့ ရေးခွင့် ပြုသည်။"</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"appအား SD ကဒ်သို့ ရေးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"appအား USB သိုလှောင်ခန်းသို့ ရေးခွင့် ပြုသည်။"</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"appအား SD ကဒ်သို့ ရေးခွင့် ပြုသည်။"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"စက်တွင်းမီဒီယာသိမ်းဆည်းမှုအကြောင်းအရာများကို မွမ်းမံ/ပယ်ဖျက်ရန်"</string>
-    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"appအား အတွင်းပိုင်း မီဒီယာ သိုလှော်ခန်း အကြေင်းအရာများကို မွမ်းမံခွင့် ပြုသည်။"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"appအား အတွင်းပိုင်း မီဒီယာ သိုလှော်ခန်း အကြေင်းအရာများကို မွမ်းမံခွင့် ပြုသည်။"</string>
     <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"စာရွက်စာတန်းများ သိုလှောင်မှုကို ထိန်းသိမ်းခြင်း"</string>
     <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"အပလီကေးရှင်းအား စာရွက်စာတမ်းများအား ထိန်းချုပ်ခွင့်ပေးခြင်း"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"အသုံးပြုသူ အားလုံး၏ ပြင်ပသိုလှောင်ရာအား အသုံးပြုရန်"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"အပလီကေးရှင်းအား သုံးစွဲသူ အားလုံးအတွက် ပြင်ပသိမ်းဆည်မှုအား သုံးခွင့် ပြုပါ။"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"cache ဖိုင်စနစ်အား ဝင်ရောက်ချိတ်ဆက်ခြင်း"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"appအား ဖိုင်စနစ်၏ကက်ရှကို ဖတ် နှင့် ရေး ခွင့်ပြုသည်။"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"appအား ဖိုင်စနစ်၏ကက်ရှကို ဖတ် နှင့် ရေး ခွင့်ပြုသည်။"</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP ခေါ်ဆိုမှုများ ခေါ်ရန်/လက်ခံရန်"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"SIP ခေါ်ဆိုမှုများ ခေါ်ရန်နှင့် လက်ခံနိုင်ရန် app ကို ခွင့်ပြုပါ။"</string>
     <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"တယ်လီကွမ် ဆင်းမ် ချိတ်ဆက်မှုများကို မှတ်ပုံတင်ပါ"</string>
-    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"appအား တယ်လီကွမ် ဆင်းမ် ချိတ်ဆက်မှုကို မှတ်ပုံတင်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"appအား တယ်လီကွမ် ဆင်းမ် ချိတ်ဆက်မှုကို မှတ်ပုံတင်ခွင့် ပြုသည်။"</string>
     <string name="permlab_register_call_provider" msgid="108102120289029841">"တယ်လီကွမ် တယ်လီကွမ် ချိတ်ဆက်မှု အသစ်များကို မှတ်ပုံတင်ပါ"</string>
-    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"appအား တယ်လီကွမ် ချိတ်ဆက်မှု အသစ်များကို မှတ်ပုံတင်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"appအား တယ်လီကွမ် ချိတ်ဆက်မှု အသစ်များကို မှတ်ပုံတင်ခွင့် ပြုသည်။"</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"တယ်လီကွမ် ဆက်သွယ်မှုများကို စီမံရန်"</string>
-    <string name="permdesc_connection_manager" msgid="5925480810356483565">"appအား တယ်လီကွမ် ဆက်သွယ်မှုများကို စီမံခွင့် ပြုပါ။"</string>
+    <string name="permdesc_connection_manager" msgid="5925480810356483565">"appအား တယ်လီကွမ် ဆက်သွယ်မှုများကို စီမံခွင့် ပြုပါ။"</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"ခေါ်ဆိုမှု-အဝင် မျက်နှာပြင်နဲ့ တုံ့ပြန်လုပ်ကိုင်ရန်"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"appအား အသုံးပြုသူက ခေါ်ဆိုမှုအဝင် မျက်နှာပြင် ဘယ်အချိန်မှာ ဘယ်လို မြင်ရမှာကို ထိန်းချုပ်ခွင့်ပေးရန်"</string>
-    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"တယ်လီဖုန်း ဝန်ဆောင်မှုများနှင့် အပြန်အလှန် တုံ့ပြန်မှု"</string>
-    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"appအား ခေါ်ဆိုမှုများ လုပ်ခြင်း/လက်ခံခြင်း ပြုလုပ်နိုင်ရန် တယ်လီဖုန်း ဝန်ဆောင်မှုများနှင့် အပြန်အလှန် တုံ့ပြန်မှုကို ခွင့်ပြုသည်။"</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"တယ်လီဖုန်း ဝန်ဆောင်မှုများနှင့် အပြန်အလှန် တုံ့ပြန်မှု"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"appအား ခေါ်ဆိုမှုများ လုပ်ခြင်း/လက်ခံခြင်း ပြုလုပ်နိုင်ရန် တယ်လီဖုန်း ဝန်ဆောင်မှုများနှင့် အပြန်အလှန် တုံ့ပြန်မှုကို ခွင့်ပြုသည်။"</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"အသုံးပြုသူ အတွက် ခေါ်ဆိုမှုအဝင် လုပ်ကိုင်ပုံကို စီစဉ်ပေးခြင်း"</string>
-    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"appအား အသုံးပြုသူ အတွက် ခေါ်ဆိုမှုအဝင် လုပ်ကိုင်ပုံကို စီစဉ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"appအား အသုံးပြုသူ အတွက် ခေါ်ဆိုမှုအဝင် လုပ်ကိုင်ပုံကို စီစဉ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ရာဇဝင်အလိုက် ကွန်ယက်သုံစွဲမှုအား ဖတ်ခြင်း"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"appအား အထူး ကွန်ရက်များ နှင့် appများ အတွက် ကွန်ရက် အသုံးပြုမှု မှတ်တမ်းကို ဖတ်ကြားခွင့် ပြုသည်။"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"appအား အထူး ကွန်ရက်များ နှင့် appများ အတွက် ကွန်ရက် အသုံးပြုမှု မှတ်တမ်းကို ဖတ်ကြားခွင့် ပြုသည်။"</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"ကွန်ယက်မူဝါဒအား စီမံခြင်း"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"appအား ကွန်ရက် မူဝါဒများကို စီမံခန့်ခွဲခွင့် နှင့် app-ဆိုင်ရာ စည်းကမ်းချက်များကို ပြဌာန်းခွင့် ပြုသည်။"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"appအား ကွန်ရက် မူဝါဒများကို စီမံခန့်ခွဲခွင့် နှင့် app-ဆိုင်ရာ စည်းကမ်းချက်များကို ပြဌာန်းခွင့် ပြုသည်။"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ကွန်ယက်အသုံးပြုမှုစာရင်းအား မွမ်းမံခြင်း"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"အပလီကေးရှင်းအား တခြားအပလီကေးရှင်းများမှ ကွန်ရက်အသုံးပြုမှု တွက်ချက်ခြင်းအား ပြင်ဆင်ခွင့် ပြုပါ။ ပုံမှန် အပလီကေးရှင်းများအတွက် မလိုအပ်ပါ။"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"သတိပေးချက်များအား အသုံးပြုခွင့်"</string>
@@ -791,31 +791,31 @@
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"သတိပေးချက် နားထောင်ခြင်း ဆားဗစ် နှင့် ပူးပေါင်းခြင်း"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"ဖုန်းကိုင်ထားသူနှင့် အကြောင်းကြားချက် နားစွင့်သော ဆားဗစ်မှ ထိပ်ပိုင်းအင်တာဖေ့စ် ကို ပူးပေါင်းခွင့်ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုအပ်ပါ"</string>
     <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"အခြေအနေ စီမံပေးရေး ဝန်ဆောင်မှု တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"စွဲကိုင်ထားသူအား အခြေအနေကို စီမံပေးသူ၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"စွဲကိုင်ထားသူအား အခြေအနေကို စီမံပေးသူ၏ ထိပ်သီး အဆင့် အင်တာဖေ့စ်သို့ ချိတ်တွဲခွင့်ကို ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_bindDreamService" msgid="4153646965978563462">"အိပ်မက် ဝန်ဆောင်မှုသို့ ပေါင်းစည်းမည်"</string>
     <string name="permdesc_bindDreamService" msgid="7325825272223347863">"အိမ်မက်ဝန်ဆောင်မှု၏ ထိပ်တန်းအဆင့် မျက်နှာပြင်အား ကိုင်ဆောင်သူမှ ပေါင်းစည်းရန် ခွင့်ပြုမည်။ သာမန် အပလီကေးရှင်းများတွင် မလိုအပ်ပါ။"</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"မိုဘိုင်းဆက်သွယ်ရေးဝန်ဆောင်မှုဌာန မှ ထည့်သွင်းပေးသော အခြေအနေများအား ပယ်ဖျက်ခြင်း"</string>
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ကိုင်ဆောင်သူအားမိုဘိုင်းဆက်သွယ်ရေးဝန်ဆောင်မှုဌာနမှ ထည့်သွင်းထားတဲ့ အပြင်အဆင်အား ပယ်ဖျက်ခွင့် ပေးခြင်း။ ပုံမှန် အပလီကေးရှင်းများမှာ မလိုပါ"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ကွန်ယက်အခြေအနေအား လေ့လာနေမှုအား နားထောင်ခွင့်"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"အပလီကေးရှင်းကို နက်ဝေါ့ ပေါ်က အခြေအနေကို သတိထားခွင့် ပေးခြင်း၊. ပုံမှန် အပလီကေးရှင်း များတွင် မလိုအပ်ပါ"</string>
-    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change ထည့်သွင်းရေး ကိရိယာ တိုင်းထွာညှိနှိုင်းမှု ပြောင်းလဲခြင်း"</string>
-    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"appအား တို့ထိရေး မျက်နှာပြင် တိုင်းထွာစံညှိမှုကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ  ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change ထည့်သွင်းရေး ကိရိယာ တိုင်းထွာညှိနှိုင်းမှု ပြောင်းလဲခြင်း"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"appအား တို့ထိရေး မျက်နှာပြင် တိုင်းထွာစံညှိမှုကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ  ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM လက်မှတ်များကို ရယူသုံးခြင်း"</string>
-    <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"အပလီကေးရှင်း တစ်ခုအား စီမံလုပ်ကိုင်ခွင့် DRM လက်မှတ်များ သုံးခွင့် ပြုသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"အပလီကေးရှင်း တစ်ခုအား စီမံလုပ်ကိုင်ခွင့် DRM လက်မှတ်များ သုံးခွင့် ပြုသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_handoverStatus" msgid="1159132046126626731">"အန်ဒရွိုက်၏ အလင်းတန်းထိုး လွှဲပြောင်းမှု အခြေအနေကို ရယူရန်"</string>
-    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ဒီအပလီကေးရှင်းအား အန်ဒရွိုက်၏ လက်ရှိ အလင်းတန်းထိုး လွှဲပြောင်းမှု အကြောင်း အချက်အလက်ကို ရယူခွင့် ပြုသည်"</string>
+    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"ဒီအပလီကေးရှင်းအား အန်ဒရွိုက်၏ လက်ရှိ အလင်းတန်းထိုး လွှဲပြောင်းမှု အကြောင်း အချက်အလက်ကို ရယူခွင့် ပြုသည်"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM လက်မှတ်များ ဖယ်ရှားရန်"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"အပလီကေးရှင်းအား DRM လက်မှတ်များကို ဖယ်ရှားခွင့် ပြုသည်။  သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"အပလီကေးရှင်းအား DRM လက်မှတ်များကို ဖယ်ရှားခွင့် ပြုသည်။  သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"စာပို့စာယူ ဆက်သွယ်ရေးဝန်ဆောင်မှုတစ်ခုအား ပူးပေါင်းခွင့်ပြုရန်"</string>
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"စာပို့စာယူဆက်သွယ်ရေးဝန်ဆောင်မှုတစ်ခု၏ ထိပ်ဆုံးရှိအင်တာဖေ့စ်ဖြင့် ပူးပေါင်းရန် ပိုင်ရှင်အားခွင့်ပြုပါ။ ပုံမှန် app များအတွက် မလိုအပ်ပါ။"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"မျက်နှာပြင် သော့ဖွင့်ရန် လိုအပ်သော စကားလုံးအရေအတွက်နှင့် အမျိုးအစားအား ထိန်းချုပ်ရန်"</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"မော်နီတာမျက်နှာပြင်ဖွင့်ရန် ကြိုးစားခွင့်များ"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် တက်ဘလက်ကို သော့ခတ်ရန် သို့မဟုတ် တက်ဘလက် ဒေတာ အားလုံးကို ဖျက်ပစ်ရန်။"</string>
-    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"ဖန်မျက်နှာပြင်အား သော့ဖွင့်စဉ် လျှို့ဝှက်ကုဒ်အမှားများ ရိုက်သွင်းမှုအား စောင့်ကြည့်ရန်နှင့်၊ လျှို့ဝှက်ကုဒ်အမှားများ များစွာ ရိုက်သွင်းပါက တီဗွီအား သော့ချခြင်း သို့မဟုတ် တီဗွီ၏ အချက်အလက်များအား ဖျက်ပစ်ခြင်းများ ပြုရန်။"</string>
-    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် ဖုန်းကို သော့ခတ်ရန် သို့မဟုတ် ဖုန်း ဒေတာ အားလုံးကို ဖျက်ပစ်ရန်။"</string>
-    <string name="policylab_resetPassword" msgid="2620077191242688955">"မျက်နှာပြင်ဖွင့်ရန်စကားဝှက်အား ပြောင်းခြင်း"</string>
-    <string name="policydesc_resetPassword" msgid="605963962301904458">"မျက်နှာပြင်ဖွင့်ရန်စကားဝှက်အား ပြောင်းခြင်း"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"မော်နီတာမျက်နှာပြင်ဖွင့်ရန် ကြိုးစားခွင့်များ"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် တက်ဘလက်ကို သော့ခတ်ရန် သို့မဟုတ် တက်ဘလက် ဒေတာ အားလုံးကို ဖျက်ပစ်ရန်။"</string>
+    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"ဖန်မျက်နှာပြင်အား သော့ဖွင့်စဉ် လျှို့ဝှက်ကုဒ်အမှားများ ရိုက်သွင်းမှုအား စောင့်ကြည့်ရန်နှင့်၊ လျှို့ဝှက်ကုဒ်အမှားများ များစွာ ရိုက်သွင်းပါက တီဗွီအား သော့ချခြင်း သို့မဟုတ် တီဗွီ၏ အချက်အလက်များအား ဖျက်ပစ်ခြင်းများ ပြုရန်။"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် ဖုန်းကို သော့ခတ်ရန် သို့မဟုတ် ဖုန်း ဒေတာ အားလုံးကို ဖျက်ပစ်ရန်။"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"မျက်နှာပြင်ဖွင့်ရန်စကားဝှက်အား ပြောင်းခြင်း"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"မျက်နှာပြင်ဖွင့်ရန်စကားဝှက်အား ပြောင်းခြင်း"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"မျက်နှာပြင်အားသော့ချရန်"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"မည်သည့်အချိန်တွင် ဖန်သားပြင်အား မည်ကဲ့သို့နည်းဖြင် သော့ချရန် ထိန်းချုပ်ခြင်း"</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"ဒေတာအားလုံးအားဖျက်ခြင်း"</string>
@@ -823,7 +823,7 @@
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"စက်ရုံထုတ်အခြေအနေအားပြန်လည်ရယူပါက တီဗွီရှိ အချက်အလက်များအား ကြိုတင်အသိပေးခြင်းမရှိဘဲ ဖျက်ပစ်နိုင်သည်။"</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"စက်ရုံထုတ် အခြေအနေအား ပြန်ပြောင်းခြင်းဖြင့် ဖုန်းရှိ အချက်အလက်များအား ကြိုတင်သတိပေးမှုမရှိပဲ ဖျက်စီးရန်"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"တကမာ္ဘလုံးဆိုင်ရာပရော်စီကို သတ်မှတ်ခြင်း"</string>
-    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"မူဝါဒအသုံးပြုခွင့်ရလျှင် စက်ပစ္စည်းတကမ္ဘာလုံးဆိုင်ရာပရော်စီအားသုံးရန် သတ်မှတ်ခြင်း။ ပထမဦးဆုံးသောစက်၏ထိန်းချုပ်သူသာ တကမ္ဘာလုံးဆိုင်ရာပရော်စီသာအားအကျိုးသက်ရောက်စေရန် သတ်မှတ်နိုင်သည်။"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"မူဝါဒအသုံးပြုခွင့်ရလျှင် စက်ပစ္စည်းတကမ္ဘာလုံးဆိုင်ရာပရော်စီအားသုံးရန် သတ်မှတ်ခြင်း။ ပထမဦးဆုံးသောစက်၏ထိန်းချုပ်သူသာ တကမ္ဘာလုံးဆိုင်ရာပရော်စီသာအားအကျိုးသက်ရောက်စေရန် သတ်မှတ်နိုင်သည်။"</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"စကားဝှက်သက်တမ်းသတ်မှတ်ရန်"</string>
     <string name="policydesc_expirePassword" msgid="1729725226314691591">"ဖန်သားပြင်သော့ချခြင်း စကားဝှက် ပြင်ဆင်ခွင့် အကြိမ်ရေအား ထိန်းချုပ်ခြင်း"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"သိုလှောင်လျို့ဝှက်ခြင်းသတ်မှတ်"</string>
@@ -946,21 +946,21 @@
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"အလုပ်အကိုင်"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"တခြား"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"ဒီအဆက်အသွယ်အား ကြည့်ရှုရန်  အပလီကေးရှင်း မတွေ့ပါ"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ကုဒ် ရိုက်ထည့်ပါ"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK နှင့် PIN ကုဒ် အသစ်ကို ရိုက်ထည့်ပါ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ကုဒ် ရိုက်ထည့်ပါ"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK နှင့် PIN ကုဒ် အသစ်ကို ရိုက်ထည့်ပါ"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK နံပါတ်"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"PIN ကုဒ် အသစ်"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"စကားဝှက် ရိုက်ရန် ထိပါ"</font></string>
-    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"သော့ဖွင့်ရန် စကားဝှက်ကို ရိုက်ထည့်ပါ"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"သော့ဖွင့်ရန် PIN ကို ရိုက်ထည့်ပါ"</string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"သော့ဖွင့်ရန် စကားဝှက်ကို ရိုက်ထည့်ပါ"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"သော့ဖွင့်ရန် PIN ကို ရိုက်ထည့်ပါ"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ပင်နံပါတ်မှားနေပါသည်"</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"သော့ဖွင့်ရန် Menu ထိုနောက်0ကိုနှိပ်ပါ"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"သော့ဖွင့်ရန် Menu ထိုနောက်0ကိုနှိပ်ပါ"</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"အရေးပေါ်နံပါတ်"</string>
     <string name="lockscreen_carrier_default" msgid="8963839242565653192">"ဆားဗစ် မရှိပါ"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"မျက်နှာပြင်အားသော့ချထားသည်"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"ဖွင့်ရန်သို့မဟုတ်အရေးပေါ်ခေါ်ဆိုခြင်းပြုလုပ်ရန် မီနူးကိုနှိပ်ပါ"</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"ဖွင့်ရန်သို့မဟုတ်အရေးပေါ်ခေါ်ဆိုခြင်းပြုလုပ်ရန် မီနူးကိုနှိပ်ပါ"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"မီးနူးကို နှိပ်ခြင်းဖြင့် သော့ဖွင့်ပါ"</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ဖွင့်ရန်ပုံစံဆွဲပါ"</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ဖွင့်ရန်ပုံစံဆွဲပါ"</string>
     <string name="lockscreen_emergency_call" msgid="5347633784401285225">"အရေးပေါ်ခေါ်ဆိုရန်"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"ခေါ်ဆိုမှုထံပြန်သွားရန်"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"မှန်ပါသည်"</string>
@@ -971,10 +971,10 @@
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"တက်ပလက်ထဲတွင်း ဆင်းကဒ် မရှိပါ"</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"တီဗွီတွင် SIM ကဒ် မရှိပါ။"</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ဖုန်းထဲတွင် ဆင်းကဒ် မရှိပါ"</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"ဆင်းမ်ကဒ် ထည့်ပါ"</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"ဆင်းမ်ကဒ် ထည့်ပါ"</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"ဆင်းမ်ကဒ် မရှိဘူး သို့မဟုတ် ဖတ်မရပါ။ ဆင်းမ်ကဒ် တစ်ခုကို ထည့်ပါ။"</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"သုံးစွဲ မရတော့သော ဆင်းကဒ်"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"သင့် ဆင်းမ်ကဒ်ကို ထာဝရ ပိတ်လိုက်ပါပြီ။\n နောက် ဆင်းမ်ကဒ် တစ်ခု အတွက် သင်၏ ကြိုးမဲ့ ဝန်ဆောင်မှု စီမံပေးသူကို ဆက်သွယ်ပါ"</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"သင့် ဆင်းမ်ကဒ်ကို ထာဝရ ပိတ်လိုက်ပါပြီ။\n နောက် ဆင်းမ်ကဒ် တစ်ခု အတွက် သင်၏ ကြိုးမဲ့ ဝန်ဆောင်မှု စီမံပေးသူကို ဆက်သွယ်ပါ"</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"ယခင် တစ်ပုဒ်"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"နောက် တစ်ပုဒ်"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"ခဏရပ်ရန်"</string>
@@ -985,24 +985,24 @@
     <string name="emergency_calls_only" msgid="6733978304386365407">"အရေးပေါ်ခေါ်ဆိုမှုသာ"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"ကွန်ရက် သော့ကျနေခြင်း"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"ဆင်းမ်ကဒ် ရဲ့ ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ် သော့ကျနေပါသည်"</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"သုံးစွဲသူ လမ်းညွှန်ကို ကြည့်ပါ သို့မဟုတ် ဖောက်သည်များ စောင့်ရှောက်ရေး ဌာနကို ဆက်သွယ်ပါ။"</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"သုံးစွဲသူ လမ်းညွှန်ကို ကြည့်ပါ သို့မဟုတ် ဖောက်သည်များ စောင့်ရှောက်ရေး ဌာနကို ဆက်သွယ်ပါ။"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ဆင်းမ်ကဒ် သော့ကျနေပါသည်"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"ဆင်းမ်ကဒ် ကို သော့ဖွင့်နေပါသည်"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ \n\nထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g>စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"သင်သည် စကားဝှက်ကို  <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"သင်သည် သင်၏ PIN <xliff:g id="NUMBER_0">%d</xliff:g>ကို ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ တက်ဘလက်ကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် Google လက်မှတ်ထိုးဝင်ရောက်သည့် အချက်အလက်ကို သုံးလျက် တီဗွီအား သော့ဖွင့်ရမည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"သင်သည် သော့ဖွင့် ပုံစံကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ ဖုန်းကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%d</xliff:g>ကြိမ်မအောင်မြင်ပါက မူလစက်ရုံ အနေအထားသို့ပြန်လည်ရောက်ရှိကာ အသုံးပြုသူ၏ဒေတာအားလုံးဆုံးရှုံးပါမည်။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"သင့်ဖုန်းအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%d</xliff:g>ကြိမ်မအောင်မြင်ပါက မူလစက်ရုံ အနေအထားသို့ပြန်လည်ရောက်ရှိကာ အသုံးပြုသူ၏ဒေတာအားလုံးဆုံးရှုံးပါမည်။"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ယခုဖုန်းကိုမူလစက်ရုံအနေအထားသို့ပြန်လည်ရောက်ရှိပါမည်။"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်၏။"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"သင့်ဖုန်းအား မှားယွင်းစွာ <xliff:g id="NUMBER">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ယခုဖုန်းကို မူလစက်ရုံအနေအထားသို့ပြန်လည်ရောက်ရှိပါမည်။"</string>
-    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်ကြိုးစားပါ"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ \n\nထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g>စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"သင်သည် စကားဝှက်ကို  <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"သင်သည် သင်၏ PIN <xliff:g id="NUMBER_0">%d</xliff:g>ကို ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ တက်ဘလက်ကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် Google လက်မှတ်ထိုးဝင်ရောက်သည့် အချက်အလက်ကို သုံးလျက် တီဗွီအား သော့ဖွင့်ရမည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"သင်သည် သော့ဖွင့် ပုံစံကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ ဖုန်းကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%d</xliff:g>ကြိမ်မအောင်မြင်ပါက မူလစက်ရုံ အနေအထားသို့ပြန်လည်ရောက်ရှိကာ အသုံးပြုသူ၏ဒေတာအားလုံးဆုံးရှုံးပါမည်။"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"သင့်ဖုန်းအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%d</xliff:g>ကြိမ်မအောင်မြင်ပါက မူလစက်ရုံ အနေအထားသို့ပြန်လည်ရောက်ရှိကာ အသုံးပြုသူ၏ဒေတာအားလုံးဆုံးရှုံးပါမည်။"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ယခုဖုန်းကိုမူလစက်ရုံအနေအထားသို့ပြန်လည်ရောက်ရှိပါမည်။"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်၏။"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"သင့်ဖုန်းအား မှားယွင်းစွာ <xliff:g id="NUMBER">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ယခုဖုန်းကို မူလစက်ရုံအနေအထားသို့ပြန်လည်ရောက်ရှိပါမည်။"</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်ကြိုးစားပါ"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"ပုံစံအားမေ့နေပါသလား"</string>
-    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"အကောင့်ဖွင့်ရန်"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"အကောင့်ဖွင့်ရန်"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"အကြိမ်ရေ များစွာ ပုံဆွဲသော့ဖွင့်ရန် ကြိုးစားခြင်း"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"သော့ဖွင့်ရန် ဂူဂဲလ် အကောင့်ဖြင့် ဝင်ပါ"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"သုံးစွဲသူ အမှတ် (အီးမေးလ်)"</string>
@@ -1012,7 +1012,7 @@
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"သုံးစွဲသူ အမည် သို့ စကားဝှင်ကို မေ့နေပါသလား။ \n"<b>"google.com/accounts/recovery"</b>" ကို သွားရောက်ပါ။"</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"စစ်ဆေးနေပါသည်…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"ဆင်းမ်ကဒ် ဖွင့်ပါ"</string>
-    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"အသံဖွင့်ထားသည်"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"အသံဖွင့်ထားသည်"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"အသံပိတ်ထားသည်"</string>
     <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ပုံစံစတင်ခြင်း"</string>
     <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ပုံစံရှင်းလင်းခြင်း"</string>
@@ -1049,9 +1049,9 @@
     <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"စက်ရုံစမ်းသပ်ခြင်းမအောင်မြင်ပါ"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"စက်ရုံစမ်းသပ်မှုမှာ စနစ်/အပ်ပလီကေးရှင်း ထည့်သွင်းထားသောpackageများကိုသာ ပံ့ပိုးမှုပေးသည်။."</string>
-    <string name="factorytest_no_action" msgid="872991874799998561">"စက်ရုံစမ်းသပ်မှုအားလုပ်ဆောင်ရန် မည်သည့်packageမှ မတွေ့ပါ။"</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"လုပ်ငန်းစနစ်ထည့်သွင်းပြီး ပြန်လည်စတင်ရန်"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"စက်ရုံစမ်းသပ်မှုမှာ စနစ်/အပ်ပလီကေးရှင်း ထည့်သွင်းထားသောpackageများကိုသာ ပံ့ပိုးမှုပေးသည်။."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"စက်ရုံစမ်းသပ်မှုအားလုပ်ဆောင်ရန် မည်သည့်packageမှ မတွေ့ပါ။"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"လုပ်ငန်းစနစ်ထည့်သွင်းပြီး ပြန်လည်စတင်ရန်"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"ဒီ \"<xliff:g id="TITLE">%s</xliff:g>\" က စာမျက်နှာက ပြောဆိုတာက:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"သေချာကြောင်း လုပ်ပါ"</string>
@@ -1082,24 +1082,24 @@
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"အပလီကေးရှင်းအား ဘရောင်ဇာမှ ယခင် သွားရောက်ထားသော URLများ၊ နေရာ အမှတ်အသားများအား ကြည့်ရှုခွင့်ပြုပါ။ မှတ်ချက်။ ဒီခွင့်ပြုချက်ကို တတိယပါတီ ဘရောင်ဇာများ နှင့် တခြား အပလီကေးရှင်းများမှ လုပ်ဆောင်မည် မဟုတ်ပါ။"</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"သင့်ရဲ့ ဝဘ် အမှတ်နေရာများနှင့် သွားလာသော မှတ်တမ်း ရေးခြင်း"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"အပလီကေးရှင်းအား ဘရောင်ဇာမှ မှတ်တမ်း သို့ မှတ်သားမှု အမှတ်များအား ပြင်ဆင်ခွင့် ပေးခြင်း။ အပလီကေးရှင်းမှ ဘရောင်ဇာ မှတ်တမ်းများကို ဖျက်ပစ်ခွင့် သို့ ပြင်ဆင်ခွင့် ရှိပါမည်။ မှတ်ချက်။ ဤခွင့်ပြုချက်ကို တတိယပါတီ ဘရောင်ဇာများ၊ တခြား အပလီကေးရှင်းများမှ သုံးမည် မဟုတ်ပါ။"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ဘရောင်ဇာ၏မှတ်တမ်း သို့မဟုတ် တီဗွီတွင်သိမ်းထားသည့် မှတ်သားချက်များအား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။ ဤသို့ပြုခြင်းသည် ဘရောင်ဇာ၏ အချက်အလက်များအား ဖျက်ပစ်ရန် သို့မဟုတ် ပြင်ဆင်ရန် app အား ခွင့်ပြုထားခြင်းဖြစ်၏။ မှတ်ချက်၊ ဤသို့ခွင့်ပြုခြင်းသည် ပြင်ပဘရောင်ဇာများ သို့မဟုတ် ဝဘ်အား ကြည့်ရှုနိုင်သည့် တစ်ခြားသော အပလီကေးရှင်းများအား သက်ရောက်မှုရှိမည် မဟုတ်ပါ။"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ဘရောင်ဇာ၏မှတ်တမ်း သို့မဟုတ် တီဗွီတွင်သိမ်းထားသည့် မှတ်သားချက်များအား ပြင်ဆင်ရန် app အား ခွင့်ပြုပါ။ ဤသို့ပြုခြင်းသည် ဘရောင်ဇာ၏ အချက်အလက်များအား ဖျက်ပစ်ရန် သို့မဟုတ် ပြင်ဆင်ရန် app အား ခွင့်ပြုထားခြင်းဖြစ်၏။ မှတ်ချက်၊ ဤသို့ခွင့်ပြုခြင်းသည် ပြင်ပဘရောင်ဇာများ သို့မဟုတ် ဝဘ်အား ကြည့်ရှုနိုင်သည့် တစ်ခြားသော အပလီကေးရှင်းများအား သက်ရောက်မှုရှိမည် မဟုတ်ပါ။"</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"အပလီကေးရှင်းအား ဘရောင်ဇာမှ မှတ်တမ်း သို့ မှတ်သားမှု အမှတ်များအား ပြင်ဆင်ခွင့် ပေးခြင်း။ အပလီကေးရှင်းမှ ဘရောင်ဇာ မှတ်တမ်းများကို ဖျက်ပစ်ခွင့် သို့ ပြင်ဆင်ခွင့် ရှိပါမည်။ မှတ်ချက်။ ဒီခွင့်ပြုချက်ကို တတိယပါတီ ဘရောင်ဇာများ၊ တခြား အပလီကေးရှင်းများမှ သုံးမည် မဟုတ်ပါ။"</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"နှိုးစက်သတ်မှတ်ရန်"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"appအား တပ်ဆင်ထားသည့် နှိုးစက်နာရီ app ထဲတွင် နှိုးစက်ကို သတ်မှတ်ခွင့် ပြုသည်။ အချို့ နှိုးစက် appများက ထိုအင်္ဂါရပ်ကို ပြီးမြောက်အောင် မလုပ်နိုင်ကြပါ။"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"appအား တပ်ဆင်ထားသည့် နှိုးစက်နာရီ app ထဲတွင် နှိုးစက်ကို သတ်မှတ်ခွင့် ပြုသည်။ အချို့ နှိုးစက် appများက ထိုအင်္ဂါရပ်ကို ပြီးမြောက်အောင် မလုပ်နိုင်ကြပါ။"</string>
     <string name="permlab_writeVoicemail" msgid="7309899891683938100">"အသံမေးလ်ကို ရေးရန်"</string>
-    <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"appအား သင်၏ အသံမေးလ် ဝင်စာများကို မွမ်းမံခွင့် နှင့် ဖယ်ရှားခွင့် ပြုသည်။"</string>
-    <string name="permlab_addVoicemail" msgid="5525660026090959044">"အသံစာပို့စနစ်အားထည့်ရန်"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"appအား သင့် အသံမေးလ် ဝင်စာသို့ စာများကို ထည့်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"appအား သင်၏ အသံမေးလ် ဝင်စာများကို မွမ်းမံခွင့် နှင့် ဖယ်ရှားခွင့် ပြုသည်။"</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"အသံစာပို့စနစ်အားထည့်ရန်"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"appအား သင့် အသံမေးလ် ဝင်စာသို့ စာများကို ထည့်ခွင့် ပြုသည်။"</string>
     <string name="permlab_readVoicemail" msgid="8415201752589140137">"အသံမေးလ်ကို  ဖတ်ရန်"</string>
-    <string name="permdesc_readVoicemail" msgid="8926534735321616550">"appအား သင်၏ အသံမေးလ်များကို ဖတ်ခွင့် ပြုရန်"</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ဘရောင်ဇာ ဘူမိဇုန်သတ်မှတ်မှု ခွင့်ပြုချက်များကို မွမ်းမံခြင်း"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"appအား ဘရောင်ဇာ၏ ဘူမိဇုန်သတ်မှတ်ရေး ခွင့်ပြုချက်များကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးချပြီး လိုရာ ဝက်ဘ်ဆိုက်များသို့ တည်နေရာ အချက်အလက် ပို့မှုကို လုပ်နိုင်သည်။"</string>
+    <string name="permdesc_readVoicemail" msgid="8926534735321616550">"appအား သင်၏ အသံမေးလ်များကို ဖတ်ခွင့် ပြုရန်"</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ဘရောင်ဇာ ဘူမိဇုန်သတ်မှတ်မှု ခွင့်ပြုချက်များကို မွမ်းမံခြင်း"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"appအား ဘရောင်ဇာ၏ ဘူမိဇုန်သတ်မှတ်ရေး ခွင့်ပြုချက်များကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် appများက ၎င်းကို အသုံးချပြီး လိုရာ ဝက်ဘ်ဆိုက်များသို့ တည်နေရာ အချက်အလက် ပို့မှုကို လုပ်နိုင်သည်။"</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"packages များကိုအတည်ပြုစိစစ်ခြင်း"</string>
-    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"appအား အထုပ် တစ်ခု၏ မတည်ငြိမ်မှုကို စိစစ်ခွင့် ပြုသည်။"</string>
-    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"package အတည်ပြုခြင်းနှင့် ပူးပေါင်းရန်"</string>
-    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"စွဲကိုင်ထားသူအား အထုပ်များအား စိစစ်ရေး တောင်းဆိုချက်များကို ပြုလုပ်ခွင့် ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"appအား အထုပ် တစ်ခု၏ မတည်ငြိမ်မှုကို စိစစ်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"package အတည်ပြုခြင်းနှင့် ပူးပေါင်းရန်"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"စွဲကိုင်ထားသူအား အထုပ်များအား စိစစ်ရေး တောင်းဆိုချက်များကို ပြုလုပ်ခွင့် ပေးသည်။ သာမန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_serialPort" msgid="546083327654631076">"အစဥ်လိုက်ပို့များကို ဝင်ရောက်ချိတ်ဆက်ခြင်း"</string>
-    <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager APIအားအသုံးပြုကာ ကိုင်ဆောင်သူကို စီရီယာပို့မျာကို ဝင်ရောက်အသုံးပြုခြင်းအား ခွင့်ပြုသည်။"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager APIအားအသုံးပြုကာ ကိုင်ဆောင်သူကို စီရီယာပို့မျာကို ဝင်ရောက်အသုံးပြုခြင်းအား ခွင့်ပြုသည်။"</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"အချက်အလက်များ ပံ့ပိုသူများအား အပြင်ဖက်မှ ရယူခြင်း"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ကိုင်ဆောင်ထားသူကို အချက်အလက်ပံ့ပိုးမှုများကို ကွန်ဆိုးလ်မှ ရယူခွင့် ပြုပါ။ ပုံမှန်အပလီကေးရှင်းအတွက် မလိုအပ်ပါ။"</string>
     <string name="permlab_updateLock" msgid="3527558366616680889">"စက်အလိုအလျောက်အဆင်မြှင့်ခြင်း အားမပေးရန်"</string>
@@ -1107,8 +1107,8 @@
     <string name="save_password_message" msgid="767344687139195790">"ဤလျှို့ဝှက်စကားဝှက်အား ဘရောင်ဇာကိုမှတ်ခိုင်းမည်လား"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"ယခုမဟုတ်ပါ"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"မှတ်ထားရန်"</string>
-    <string name="save_password_never" msgid="8274330296785855105">"မည်သည့်အခါမှ"</string>
-    <string name="open_permission_deny" msgid="7374036708316629800">"သင့်ဆီမှာ ဒီစာမျက်နှာကို ဖွင့်ရန် ခွင့်ပြုချက် မရှိပါ။"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"မည်သည့်အခါမှ"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"သင့်ဆီမှာ ဒီစာမျက်နှာကို ဖွင့်ရန် ခွင့်ပြုချက် မရှိပါ။"</string>
     <string name="text_copied" msgid="4985729524670131385">"clipboardထံ စာသားအားကူးယူမည်"</string>
     <string name="more_item_label" msgid="4650918923083320495">"နောက်ထပ်"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
@@ -1128,8 +1128,8 @@
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"လွန်ခဲ့သော၁လက"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"လွန်ခဲ့သော၁လမတိုင်မီက"</string>
   <plurals name="num_seconds_ago">
-    <item quantity="one" msgid="4869870056547896011">"လွန်ခဲ့သော ၁စက္ကန့်က"</item>
-    <item quantity="other" msgid="3903706804349556379">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်က"</item>
+    <item quantity="one" msgid="4869870056547896011">"လွန်ခဲ့သော ၁စက္ကန့်က"</item>
+    <item quantity="other" msgid="3903706804349556379">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်က"</item>
   </plurals>
   <plurals name="num_minutes_ago">
     <item quantity="one" msgid="3306787433088810191">"လွန်ခဲ့သော ၁မိနစ်က"</item>
@@ -1149,8 +1149,8 @@
     <item quantity="other" msgid="2479586466153314633">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> ရက်တွင်"</item>
   </plurals>
   <plurals name="in_num_seconds">
-    <item quantity="one" msgid="2729745560954905102">"နောက် ၁စက္ကန့်တွင်"</item>
-    <item quantity="other" msgid="1241926116443974687">"နောက် <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်တွင်"</item>
+    <item quantity="one" msgid="2729745560954905102">"နောက် ၁စက္ကန့်တွင်"</item>
+    <item quantity="other" msgid="1241926116443974687">"နောက် <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်တွင်"</item>
   </plurals>
   <plurals name="in_num_minutes">
     <item quantity="one" msgid="8793095251325200395">"နောက်၁မီနစ်တွင်"</item>
@@ -1165,8 +1165,8 @@
     <item quantity="other" msgid="5109449375100953247">"နောက် <xliff:g id="COUNT">%d</xliff:g> ရက်တွင်"</item>
   </plurals>
   <plurals name="abbrev_num_seconds_ago">
-    <item quantity="one" msgid="1849036840200069118">"လွန်ခဲ့သော ၁စက္ကန့်က"</item>
-    <item quantity="other" msgid="3699169366650930415">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်က"</item>
+    <item quantity="one" msgid="1849036840200069118">"လွန်ခဲ့သော ၁စက္ကန့်က"</item>
+    <item quantity="other" msgid="3699169366650930415">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်က"</item>
   </plurals>
   <plurals name="abbrev_num_minutes_ago">
     <item quantity="one" msgid="6361490147113871545">"လွန်ခဲ့သော ၁မိနစ်က"</item>
@@ -1181,8 +1181,8 @@
     <item quantity="other" msgid="3453342639616481191">"လွန်ခဲ့သော <xliff:g id="COUNT">%d</xliff:g> ရက်တွင်"</item>
   </plurals>
   <plurals name="abbrev_in_num_seconds">
-    <item quantity="one" msgid="5842225370795066299">"နောက် ၁စက္ကန့်တွင်"</item>
-    <item quantity="other" msgid="5495880108825805108">"နောက် <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်တွင်"</item>
+    <item quantity="one" msgid="5842225370795066299">"နောက် ၁စက္ကန့်တွင်"</item>
+    <item quantity="other" msgid="5495880108825805108">"နောက် <xliff:g id="COUNT">%d</xliff:g> စက္ကန့်တွင်"</item>
   </plurals>
   <plurals name="abbrev_in_num_minutes">
     <item quantity="one" msgid="562786149928284878">"နောက်၁မိနစ်တွင်"</item>
@@ -1205,8 +1205,8 @@
     <string name="hours" msgid="894424005266852993">"နာရီများ"</string>
     <string name="minute" msgid="9148878657703769868">"မိနစ်"</string>
     <string name="minutes" msgid="5646001005827034509">"မိနစ်"</string>
-    <string name="second" msgid="3184235808021478">"စက္ကန့်"</string>
-    <string name="seconds" msgid="3161515347216589235">"စက္ကန့်"</string>
+    <string name="second" msgid="3184235808021478">"စက္ကန့်"</string>
+    <string name="seconds" msgid="3161515347216589235">"စက္ကန့်"</string>
     <string name="week" msgid="5617961537173061583">"အပတ်"</string>
     <string name="weeks" msgid="6509623834583944518">"အပတ်"</string>
     <string name="year" msgid="4001118221013892076">"နှစ်"</string>
@@ -1224,12 +1224,12 @@
     <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> နာရီ"</item>
   </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"ဗီဒီယို ပြဿနာ"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ဒီဗိဒီယိုမှာ ဒီကိရိယာ ပေါ်မှာ ဖွင့်ကြည့်၍ မရနိုင်ပါ။"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ဒီဗိဒီယိုမှာ ဒီကိရိယာ ပေါ်မှာ ဖွင့်ကြည့်၍ မရနိုင်ပါ။"</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ဒီဗီဒီယိုကို ပြသလို့ မရပါ"</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"ကောင်းပြီ"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="noon" msgid="7245353528818587908">"မွန်းတည့်"</string>
-    <string name="Noon" msgid="3342127745230013127">"မွန်းတည့်"</string>
+    <string name="noon" msgid="7245353528818587908">"မွန်းတည့်"</string>
+    <string name="Noon" msgid="3342127745230013127">"မွန်းတည့်"</string>
     <string name="midnight" msgid="7166259508850457595">"ညသန်းခေါင်"</string>
     <string name="Midnight" msgid="5630806906897892201">"ညသန်းခေါင်"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
@@ -1245,11 +1245,11 @@
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"စာတိုရွေးချယ်မှု"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"အဘိဓာန်ထဲ ထည့်ပါ"</string>
     <string name="deleteText" msgid="6979668428458199034">"ဖျက်ပစ်ရန်"</string>
-    <string name="inputMethod" msgid="1653630062304567879">"ထည့်သွင်းရန်နည်းလမ်း"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ထည့်သွင်းရန်နည်းလမ်း"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"စာတို လုပ်ဆောင်ချက်"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"သိမ်းဆည်သော နေရာ နည်းနေပါသည်"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"တချို့ စနစ်လုပ်ငန်းများ အလုပ် မလုပ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"စနစ်အတွက် သိုလှောင်ခန်း မလုံလောက်ပါ။ သင့်ဆီမှာ နေရာလွတ် ၂၅၀ MB ရှိတာ စစ်ကြည့်ပြီး စတင်ပါ။"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"စနစ်အတွက် သိုလှောင်ခန်း မလုံလောက်ပါ။ သင့်ဆီမှာ နေရာလွတ် ၂၅၀ MB ရှိတာ စစ်ကြည့်ပြီး စတင်ပါ။"</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> က အလုပ်လုပ်နေသည်။"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"အချက်အလက်များ ပိုသိရန် သို့မဟုတ် အပလီကေးရှင်းကို ရပ်ရန် တို့ထိလိုက်ပါ။"</string>
     <string name="ok" msgid="5970060430562524910">"ကောင်းပြီ"</string>
@@ -1264,10 +1264,10 @@
     <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s ကို သုံးပြီး လုပ်ဆောင်ချက် ပြီးဆုံးပါစေ"</string>
     <string name="whichViewApplication" msgid="3272778576700572102">"...ဖြင့် ဖွင့်မည်"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ဖြင့် ဖွင့်မည်"</string>
-    <string name="whichEditApplication" msgid="144727838241402655">"...နှင့် တည်းဖြတ်ရန်"</string>
-    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s နှင့် တည်းဖြတ်ရန်"</string>
-    <string name="whichSendApplication" msgid="6902512414057341668">"...နှင့် မျှဝေရန်"</string>
-    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$sနှင့် မျှဝေရန်"</string>
+    <string name="whichEditApplication" msgid="144727838241402655">"...နှင့် တည်းဖြတ်ရန်"</string>
+    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s နှင့် တည်းဖြတ်ရန်"</string>
+    <string name="whichSendApplication" msgid="6902512414057341668">"...နှင့် မျှဝေရန်"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$sနှင့် မျှဝေရန်"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"ပင်မ appကို ရွေးပါ"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"%1$sကို ပင်မအဖြစ် သုံးပါ"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"ဤလှုပ်ရှားမှုအတွက် မူရင်းအတိုင်း အသုံးပြုပါ။"</string>
@@ -1277,8 +1277,8 @@
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB ကိရိယာ အတွက် app တစ်ခု ရွေးပါ"</string>
     <string name="noApplications" msgid="2991814273936504689">"ဘယ် appကမှ ဒီ လုပ်ဆောင်ချက်ကို မလုပ်ကိုင်နိုင်ပါ။"</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
-    <string name="aerr_application" msgid="932628488013092776">"ဝမ်းနည်းစွာဖြင့်<xliff:g id="APPLICATION">%1$s</xliff:g>မှာ ရပ်ဆိုင်းသွားသည်။"</string>
-    <string name="aerr_process" msgid="4507058997035697579">"ဝမ်းနည်းစွာဖြင့် လုပ်ဆောင်ချက်<xliff:g id="PROCESS">%1$s</xliff:g>မှာ ရပ်ဆိုင်းသွားသည်။"</string>
+    <string name="aerr_application" msgid="932628488013092776">"ဝမ်းနည်းစွာဖြင့်<xliff:g id="APPLICATION">%1$s</xliff:g>မှာ ရပ်ဆိုင်းသွားသည်။"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"ဝမ်းနည်းစွာဖြင့် လုပ်ဆောင်ချက်<xliff:g id="PROCESS">%1$s</xliff:g>မှာ ရပ်ဆိုင်းသွားသည်။"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> က မတုံ့ပြန်ပါ။ \n\n၎င်းကို သင် ပိတ်လိုပါသလား?"</string>
     <string name="anr_activity_process" msgid="5776209883299089767">"လှုပ်ရှားမှု <xliff:g id="ACTIVITY">%1$s</xliff:g>က မတုံ့ပြန်ပါ။\n\n၎င်းကို သင် ပိတ်လိုပါသလား?"</string>
@@ -1286,37 +1286,37 @@
     <string name="anr_process" msgid="6513209874880517125">"ဖြစ်စဉ်<xliff:g id="PROCESS">%1$s</xliff:g> က မတုံ့ပြန်ပါ။ \n\n၎င်းကို သင် ပိတ် ချင်သလား?"</string>
     <string name="force_close" msgid="8346072094521265605">"ကောင်းပြီ"</string>
     <string name="report" msgid="4060218260984795706">"သတင်းပို့ပါ"</string>
-    <string name="wait" msgid="7147118217226317732">"စောင့်ဆိုင်းရန်"</string>
+    <string name="wait" msgid="7147118217226317732">"စောင့်ဆိုင်းရန်"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"စာမျက်နှာမှာ ပြန်လည် တုံ့ပြန်မှု မရှိတော့ပါ။\n\nပိတ်လိုက်ချင်ပါသလား?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App ပြန်ညွှန်းခဲ့"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ယခုအလုပ်လုပ်နေသည်"</string>
-    <string name="launch_warning_original" msgid="188102023021668683">"မူလ <xliff:g id="APP_NAME">%1$s</xliff:g> တွင် ထုတ်လွင့်သည်"</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"မူလ <xliff:g id="APP_NAME">%1$s</xliff:g> တွင် ထုတ်လွင့်သည်"</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"စကေး"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"အမြဲပြသရန်"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ဒါကို စနစ် ဆက်တင်များထဲ ပြန်ဖွင့်ပေးရန် &gt; Apps &gt; ဒေါင်းလုဒ် လုပ်ပြီး။"</string>
-    <string name="smv_application" msgid="3307209192155442829">"app <xliff:g id="APPLICATION">%1$s</xliff:g> (လုပ်ငန်းစဉ် <xliff:g id="PROCESS">%2$s</xliff:g>) က ကိုယ်တိုင် ပြဌာန်းခဲ့သည့် StrictMode မူဝါဒကို ချိုးဖောက်ခဲ့သည်။"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"ဒါကို စနစ် ဆက်တင်များထဲ ပြန်ဖွင့်ပေးရန် &gt; Apps &gt; ဒေါင်းလုဒ် လုပ်ပြီး။"</string>
+    <string name="smv_application" msgid="3307209192155442829">"app <xliff:g id="APPLICATION">%1$s</xliff:g> (လုပ်ငန်းစဉ် <xliff:g id="PROCESS">%2$s</xliff:g>) က ကိုယ်တိုင် ပြဌာန်းခဲ့သည့် StrictMode မူဝါဒကို ချိုးဖောက်ခဲ့သည်။"</string>
     <string name="smv_process" msgid="5120397012047462446">"ဤ<xliff:g id="PROCESS">%1$s</xliff:g>ဖြစ်စဥ်မှာ ကိုယ်တိုင်အကျိုးသက်ရောက်သော StrictModeမူဝါဒအား ချိုးဖောက်သည်"</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"အန်ဒရွိုက်ကို မွမ်းမံနေ…"</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android စတင်နေ…"</string>
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"သိုလှောင်မှုအား ပြုပြင်ခြင်း။"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> ထဲက app<xliff:g id="NUMBER_1">%2$d</xliff:g>ကို ဆီလျော်အောင် လုပ်နေ"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"appများကို စတင်နေ"</string>
-    <string name="android_upgrading_complete" msgid="1405954754112999229">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> က အလုပ်လုပ်နေသည်"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"ppဆီ ပြောင်းရန် ထိပါ"</string>
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"appများကို ပြောင်းမလား?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"အခြား app တစ်ခု အလုပ်လုပ်နေ၍ သင်က အသစ် တစ်ခုကို မစမီ ၎င်းကို ရပ်ပစ်ရမည်။"</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>သို့ပြန်သွားရန်"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"pp အသစ်ကို မစတင်ပါနှင့်။"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"pp အသစ်ကို မစတင်ပါနှင့်။"</string>
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>စတင်ပါ"</string>
     <string name="new_app_description" msgid="1932143598371537340">"app အဟောင်းကို မသိမ်းဆည်းဘဲ ရပ်လိုက်ပါ။"</string>
     <string name="sendText" msgid="5209874571959469142">"စာတိုအတွက် လုပ်ဆောင်ချက် ရေးပါ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ဖုန်းမြည်သံအတိုးအကျယ်"</string>
     <string name="volume_music" msgid="5421651157138628171">"မီဒီယာအသံအတိုးအကျယ်"</string>
-    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ဘလူးတူးသ်မှတဆင့်ဖွင့်ရန်"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ဘလူးတူးသ်မှတဆင့်ဖွင့်ရန်"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"အသံတိတ် မြည်သံ သတ်မှတ်ရန်"</string>
     <string name="volume_call" msgid="3941680041282788711">"ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
-    <string name="volume_bluetooth_call" msgid="2002891926351151534">"ဘလူးတုသ်ဖြင့် ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"ဘလူးတုသ်ဖြင့် ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"နှိုးစက်သံအတိုးအကျယ်"</string>
     <string name="volume_notification" msgid="2422265656744276715">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"အသံအတိုးအကျယ်"</string>
@@ -1335,8 +1335,8 @@
     <item quantity="other" msgid="4192424489168397386">"ဝိုင်ဖိုင်ကွန်ယက်များရှိသည်"</item>
   </plurals>
   <plurals name="wifi_available_detailed">
-    <item quantity="one" msgid="1634101450343277345">"ဖွင့်ထားသောဝိုင်ဖိုင်ကွန်ယက်ရှိသည်"</item>
-    <item quantity="other" msgid="7915895323644292768">"ဖွင့်ထားသောဝိုင်ဖိုင်ကွန်ယက်များရှိသည်"</item>
+    <item quantity="one" msgid="1634101450343277345">"ဖွင့်ထားသောဝိုင်ဖိုင်ကွန်ယက်ရှိသည်"</item>
+    <item quantity="other" msgid="7915895323644292768">"ဖွင့်ထားသောဝိုင်ဖိုင်ကွန်ယက်များရှိသည်"</item>
   </plurals>
     <string name="wifi_available_sign_in" msgid="4029489716605255386">"ဝိုင်ဖိုင်ကွန်ရက်သို့ ဝင်ပါ"</string>
     <string name="network_available_sign_in" msgid="8495155593358054676">"ကွန်ရက်သို့ ဝင်ပါ"</string>
@@ -1347,7 +1347,7 @@
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"တိုက်ရိုက် ဝိုင်ဖိုင်"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"တိုက်ရိုက်ဝိုင်ဖိုင်ကို စတင်ပါ။ ၎င်းသည် ဝိုင်ဖိုင် ဟော့စပေါ့ကို ရပ်ဆိုင်းစေမှာ ဖြစ်ပါသည်။"</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"တိုက်ရိုက်ဝိုင်ဖိုင်ကို စတင်လို့ မရပါ"</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"ဝိုင်ဖိုင် တိုက်ရိုက် ကိုဖွင့်ထားသည်"</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"ဝိုင်ဖိုင် တိုက်ရိုက် ကိုဖွင့်ထားသည်"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"အပြင်အဆင်များအတွက်ထိပါ"</string>
     <string name="accept" msgid="1645267259272829559">"လက်ခံရန်"</string>
     <string name="decline" msgid="2112225451706137894">"လက်မခံပါ"</string>
@@ -1358,16 +1358,16 @@
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"လိုအပ်သော ပင် နံပါတ် ရိုက်ရန်:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ပင် နံပါတ်:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> နှင့် ဆက်သွယ်ထားစဉ် တက်ဘလက်ဟာ ဝိုင်ဖိုင် နှင့် ဆက်သွယ်မှု ရပ်ဆိုင်းထားမှာ ဖြစ်ပါတယ်"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"တီဗွီအား <xliff:g id="DEVICE_NAME">%1$s</xliff:g> နှင့် ချိတ်ဆက်ထားစဉ် ဝိုင်ဖိုင်နှင့် ချိတ်ဆက်မှုအား ယာယီဖြုတ်ထားမည်။"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"တီဗွီအား <xliff:g id="DEVICE_NAME">%1$s</xliff:g> နှင့် ချိတ်ဆက်ထားစဉ် ဝိုင်ဖိုင်နှင့် ချိတ်ဆက်မှုအား ယာယီဖြုတ်ထားမည်။"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို ဆက်သွယ်ထားစဉ် ဖုန်းအား ဝိုင်ဖိုင်မှ ဆက်သွယ်မှု ရပ်ဆိုင်းထားပါမည်"</string>
-    <string name="select_character" msgid="3365550120617701745">"စာရိုက်ထည့်ရန်"</string>
-    <string name="sms_control_title" msgid="7296612781128917719">"စာတိုပို့စနစ်(SMS)ဖြင့် စာများ ပို့သည်"</string>
+    <string name="select_character" msgid="3365550120617701745">"စာရိုက်ထည့်ရန်"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"စာတိုပို့စနစ်(SMS)ဖြင့် စာများ ပို့သည်"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; မှ စာ အမြောက်အများ ပို့နေပါသည်။ ဒီအပလီကေးရှင်းကို ဆက်လက်ပြီး လုပ်ဆောင်ရန် ခွင့်ပြုပါမလား"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"ခွင့်ပြုရန်"</string>
     <string name="sms_control_no" msgid="625438561395534982">"ငြင်းပယ်ခြင်း"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; မှ &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ကို စာတို ပို့ချင်ပါသည်"</string>
-    <string name="sms_short_code_details" msgid="5873295990846059400"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် "</b>" ကုန်ကျမှု ရှိလာနိုင်သည်။"</string>
-    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် ကုန်ကျမှု ရှိလာနိုင်သည်။"</b></string>
+    <string name="sms_short_code_details" msgid="5873295990846059400"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် "</b>" ကုန်ကျမှု ရှိလာနိုင်သည်။"</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် ကုန်ကျမှု ရှိလာနိုင်သည်။"</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ပို့ရန်"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ထားတော့"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ကျွန်ပ်၏ရွေးချယ်မှုကို မှတ်ထားရန်"</string>
@@ -1375,10 +1375,10 @@
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"အမြဲခွင့်ပြုရန်"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ဘယ်တော့မှခွင့်မပြုပါ"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIMကဒ်ဖယ်ရှားခြင်း"</string>
-    <string name="sim_removed_message" msgid="5450336489923274918">"သင်က မှန်ကန်သည့် ဆင်းမ် ကဒ် တစ်ခုနှင့် ပြန်မစမချင်း ဆယ်လူလာ ကွန်ရက်ကို ရှာတွေ့မည် မဟုတ်ပါ။"</string>
+    <string name="sim_removed_message" msgid="5450336489923274918">"သင်က မှန်ကန်သည့် ဆင်းမ် ကဒ် တစ်ခုနှင့် ပြန်မစမချင်း ဆယ်လူလာ ကွန်ရက်ကို ရှာတွေ့မည် မဟုတ်ပါ။"</string>
     <string name="sim_done_button" msgid="827949989369963775">"ပြီးပါပြီ"</string>
-    <string name="sim_added_title" msgid="3719670512889674693">"ဆင်းမ်ကဒ် ထည့်ပါသည်"</string>
-    <string name="sim_added_message" msgid="7797975656153714319">"ဆယ်လူလာ ကွန်ရက်ကို ရယူသုံးရန် သင့် ကိရိယာကို ပြန်ဖွင့်ပေးပါ။"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"ဆင်းမ်ကဒ် ထည့်ပါသည်"</string>
+    <string name="sim_added_message" msgid="7797975656153714319">"ဆယ်လူလာ ကွန်ရက်ကို ရယူသုံးရန် သင့် ကိရိယာကို ပြန်ဖွင့်ပေးပါ။"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"အစက ပြန်စရန်"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"အချိန်သတ်မှတ်ရန်"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"ရက်စွဲ အတည်ပြုရန်"</string>
@@ -1386,13 +1386,13 @@
     <string name="date_time_done" msgid="2507683751759308828">"ပြီးပါပြီ"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"အသစ်: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g> မှ ထောက်ပံ့သည်"</string>
-    <string name="no_permissions" msgid="7283357728219338112">"ခွင့်ပြုချက်မလိုအပ်ပါ"</string>
+    <string name="no_permissions" msgid="7283357728219338112">"ခွင့်ပြုချက်မလိုအပ်ပါ"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"သင့်အတွက် ပိုက်ဆံကုန်ကျနိုင်ပါသည်"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB ဖြင့်အချက်အလက်မြောက်များစွာ သိမ်းဆည်းနိုင်သော နေရာ"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB ချိန်ဆက်ထားပြီး"</string>
     <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"သင့်ကွန်ပျူတာကို USB မှ တဆင့် ဆက်သွယ်ထားပါသည်။ ကွန်ပျူတာနဲ့ အန်းဒရွိုက်၏ USB သိုလှောင်မှု အကြား အချက်အလက် လွှဲပြောင်းရန် တို့ထိပါ"</string>
     <string name="usb_storage_message" product="default" msgid="805351000446037811">"သင့်ကွန်ပျူတာကို USB မှ တဆင့် ဆက်သွယ်ထားပါသည်။ ကွန်ပျူတာနဲ့ အန်းဒရွိုက်၏ SD ကဒ် အကြား အချက်အလက် လွှဲပြောင်းရန် တို့ထိပါ"</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USBသိမ်းဆည်းခြင်းကိုဖွင့်ရန်"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USBသိမ်းဆည်းခြင်းကိုဖွင့်ရန်"</string>
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB ကို သုံးပြီး USB ဖြင့်အချက်အလက်မြောက်များစွာ သိမ်းဆည်းနိုင်သော နေရာတွင် ပြသနာ ဖြစ်နေပါသည်"</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD card ကို သုံးပြီး USB ဖြင့်အချက်အလက်မြောက်များစွာ သိမ်းဆည်းနိုင်သော နေရာတွင် ပြသနာ ဖြစ်နေပါသည်"</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB ချိန်ဆက်ထားပြီး"</string>
@@ -1404,19 +1404,19 @@
     <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB သိုလှောင်မှုကို မပိတ်ခင်, ကွန်ပျူတာမှ Android ၏ SD ကဒ်ကို ဖြုတ်ပါ (\"eject\")"</string>
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USBသိမ်းဆည်းခြင်းကိုပိတ်ရန်"</string>
     <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB သိုလှောင်မှု ပိတ်ရာတွင် ပြသနာရှိပါသည်။ USB လာရာအား မဆက်သွယ်ထားကြောင်း စစ်ဆေးပြီး ပြန်လည်ကြိုးစားပါ"</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USBသိမ်းဆည်းခြင်းကိုဖွင့်ရန်"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USBသိမ်းဆည်းခြင်းကိုဖွင့်ရန်"</string>
     <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"သင် ယူအက်စ်ဘီ နဲ့ သိမ်းဆည်းမှုကို ဖွင့်လိုက်ပါက တချို့ အပလီကေးရှင်းများ က ယူအက်စ်ဘီ နဲ့ သိမ်းဆည်းမှု ပြန်ပိတ်သည်အထိ အလုပ်မလုပ် သို့ သုံးစွဲရန် ရှိနေမည် မဟုတ်ပါ"</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USBဆောင်ရွက်မှုမအောင်မြင်ပါ"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ကောင်းပြီ"</string>
-    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"မီဒီယာစက်အနေဖြင့် ချိတ်ဆက်သည်"</string>
-    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ကင်မရာအနေဖြင့်ဆက်သွယ်ခြင်း"</string>
-    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"installerအနေဖြင့် ချိတ်ဆက်သည်"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"မီဒီယာစက်အနေဖြင့် ချိတ်ဆက်သည်"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ကင်မရာအနေဖြင့်ဆက်သွယ်ခြင်း"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"installerအနေဖြင့် ချိတ်ဆက်သည်"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBတွဲဖက်ပစ္စည်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_notification_message" msgid="2290859399983720271">"အခြား USB စိတ်ကြိုက်ရွေးချယ်ခွင့်များ အတွက် တို့ထိပါ။"</string>
     <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB သိုလှောင်ခန်းကို ပုံစံပြန်ချမလား?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD ကဒ်ကို ပုံစံပြန်ချမလား?"</string>
-    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"သင်၏ USB သိုလှောင်ခန်းထဲ သိုလှောင်ထားသည့် ဖိုင်အားလုံး ဖျက်ခံရမည်။ ဒီလုပ်ရပ်ကို ပြန်ပြီး ပြောင်းလဲ မရနိုင်ပါ။"</string>
-    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"သင့် ကဒ် ထဲက ဒေတာ အားလုံး ဆုံးသွားမည်။"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"သင်၏ USB သိုလှောင်ခန်းထဲ သိုလှောင်ထားသည့် ဖိုင်အားလုံး ဖျက်ခံရမည်။ ဒီလုပ်ရပ်ကို ပြန်ပြီး ပြောင်းလဲ မရနိုင်ပါ။"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"သင့် ကဒ် ထဲက ဒေတာ အားလုံး ဆုံးသွားမည်။"</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"ပုံစံချရန်ပြင်ဆင်သည်"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ဒီဘာဂင် ပိတ်ရန် ထိပါ။"</string>
@@ -1428,9 +1428,9 @@
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"လက်ကွက် အပြင်အဆင်ရွေးရန် တို့ထိပါ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="candidates_style" msgid="4333913089637062257"><u>"ရွေးချယ်ခံမည့်သူ"</u></string>
-    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USBသိမ်းဆည်းသည့်အရာအားအဆင်သင့်စေရန်ပြုလုပ်ခြင်း"</string>
-    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SDကဒ်အအဆင်သင့်စေရန်ပြုလုပ်ခြင်း"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"ရွေးချယ်ခံမည့်သူ"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USBသိမ်းဆည်းသည့်အရာအားအဆင်သင့်စေရန်ပြုလုပ်ခြင်း"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SDကဒ်အအဆင်သင့်စေရန်ပြုလုပ်ခြင်း"</string>
     <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"မှားယွင်းမှုရှိမရှိစစ်ခြင်း"</string>
     <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"USBသိမ်းဆည်းမှု၌ ဘာမှမရှိပါ"</string>
     <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"SDကဒ်ထဲ၌ဘာမှမရှိပါ"</string>
@@ -1442,19 +1442,19 @@
     <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD ကဒ် ပျက်စီးနေပါသည်။ ပြန်လည် ဖောမက် ချကြည့်ပါ"</string>
     <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"မရည်ရွယ်ပဲ USBသိုလှောင်ကိရိယာဖယ်ရှားသည်"</string>
     <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"မထင်မှတ်ပဲSDကဒ်ဖြုတ်သည်"</string>
-    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ဒေတာမဆုံးရှုံးစေရန် မပြုတ်ခင် USB သိမ်းဆည်းခြင်းအား မဖြုတ်ပါနှင့်"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ဒေတာမဆုံးရှုံးစေရန် မပြုတ်ခင် USB သိမ်းဆည်းခြင်းအား မဖြုတ်ပါနှင့်"</string>
     <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"ဒေတာမဆုံးရှုံးစေရန် မပြုတ်ခင် SDကဒ်အားမတပ်ရန်"</string>
     <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB ကိရိယာအား ဖြုတ်နိုင်သည်"</string>
     <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"အန္တရာယ်ကင်းစွာSDကဒ်အား ဖယ်နိုင်ပါပြီ"</string>
-    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USBသိမ်းဆည်းသည့်အရာအား အန္တရာယ်ကင်းစွာဖယ်နိုင်ပါပြီ"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USBသိမ်းဆည်းသည့်အရာအား အန္တရာယ်ကင်းစွာဖယ်နိုင်ပါပြီ"</string>
     <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SDကဒ်အား အန္တရာယ်ကင်းစွာဖယ်နိုင်ပါပြီ"</string>
     <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USBသိုလှောင်ကိရိယာအား ဖြုတ်သည်"</string>
     <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SDကဒ်ဖယ်ထားသည်"</string>
-    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USBသိမ်းဆည်းသည့်အရာ ဖယ်ရှားလိုက်သည်။ နောက်မီဒီယာအသစ်တခုအားထည့်ပါ။"</string>
-    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SDကဒ်အားဖယ်ရှားလိုက်သည်။ နောက်အသစ်တခုအားထည့်ပါ။"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USBသိမ်းဆည်းသည့်အရာ ဖယ်ရှားလိုက်သည်။ နောက်မီဒီယာအသစ်တခုအားထည့်ပါ။"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SDကဒ်အားဖယ်ရှားလိုက်သည်။ နောက်အသစ်တခုအားထည့်ပါ။"</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"တိုက်ဆိုင်သော ပြုလုပ်ချက် ရှာမတွေ့ပါ"</string>
-    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"အစိတ်အပိုင်းများသုံစွဲခြင်း ကိန်းဂဏန်းအချက်အလက်များကို အဆင်မြှင့်ရန်ပြုလုပ်ခြင်း"</string>
-    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"appအား စုစည်းထားသည့် အစိတ်အပိုင်း၏ သုံးစွဲမှု စာရင်းအင်းများကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"အစိတ်အပိုင်းများသုံစွဲခြင်း ကိန်းဂဏန်းအချက်အလက်များကို အဆင်မြှင့်ရန်ပြုလုပ်ခြင်း"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"appအား စုစည်းထားသည့် အစိတ်အပိုင်း၏ သုံးစွဲမှု စာရင်းအင်းများကို မွမ်းမံခွင့် ပြုသည်။ သာမန် appများ အသုံးပြုရန် မဟုတ်ပါ။"</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"အကြောင်းအရာ ကော်ပီ လုပ်ရန်"</string>
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"appအား ပုံသေ ကွန်တင်နား  ဝန်ဆောင်မှု၏ အကြောင်းအရာကို ကူးယူရန် တောင်းခံနိုင်သည်။ သာမန် appများ သုံးရန် မဟုတ်ပါ။"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"မီဒီယာထွက်ပေါက်အား လမ်းလွှဲပြောင်းခြင်း"</string>
@@ -1464,19 +1464,19 @@
     <string name="permlab_control_keyguard" msgid="172195184207828387">"keyguard အား ပြသခြင်း ကွယ်ဖျောက်ခြင်းများအား ထိန်းချုပ်ခြင်း"</string>
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"အပလီကေးရှင်း ကို keguard secure storage အား ထိန်းချုပ်ခွင့်ပေးခြင်း"</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"ယုံကြည်မှု အခြေအနေ ပြောင်းလဲမှုများကို စူးစမ်းခြင်း။"</string>
-    <string name="permdesc_trust_listener" msgid="8233895334214716864">"အပလီကေးရှင်းအား ယုံကြည်မှု အခြေအနေ ထဲက အပြောင်းအလဲများကို စူးစမ်းခွင့် ပြုသည်။"</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ယုံကြည်မှု အေဂျင့် စီစဉ်ပေးသည်။"</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"အပလီကေးရှင်းအား ယုံကြည်မှု အေဂျင့် စီစဉ်ခွင့် ပေးသည်။"</string>
-    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"ယုံကြည်ရ အေဂျင့် ဆက်တင် မီနူး ဖွင့်တင်ပါ။"</string>
-    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"အပလီကေးရှင်း တစ်ခုအား ယုံကြည်ရ အေဂျင့်၏ ပြုမူပုံကို ပြောင်းလဲစေနိုင်သည့် လှုပ်ရှားမှု တစ်ခုကို ဖွင့်တင်ခွင့် ပြုသည်။"</string>
-    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ယုံကြည်မှု အေဂျင့် ဝန်ဆောင်မှု တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
-    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"စွဲကိုင်ထားသူအား ယုံကြည်မှု အေဂျင့် ဝန်ဆောင်မှုသို့ ချိတ်တွဲခွင့်ကို ပေးသည်။"</string>
+    <string name="permdesc_trust_listener" msgid="8233895334214716864">"အပလီကေးရှင်းအား ယုံကြည်မှု အခြေအနေ ထဲက အပြောင်းအလဲများကို စူးစမ်းခွင့် ပြုသည်။"</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"ယုံကြည်မှု အေဂျင့် စီစဉ်ပေးသည်။"</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"အပလီကေးရှင်းအား ယုံကြည်မှု အေဂျင့် စီစဉ်ခွင့် ပေးသည်။"</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"ယုံကြည်ရ အေဂျင့် ဆက်တင် မီနူး ဖွင့်တင်ပါ။"</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"အပလီကေးရှင်း တစ်ခုအား ယုံကြည်ရ အေဂျင့်၏ ပြုမူပုံကို ပြောင်းလဲစေနိုင်သည့် လှုပ်ရှားမှု တစ်ခုကို ဖွင့်တင်ခွင့် ပြုသည်။"</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"ယုံကြည်မှု အေဂျင့် ဝန်ဆောင်မှု တစ်ခုဆီသို့ ချိတ်တွဲခြင်း"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"စွဲကိုင်ထားသူအား ယုံကြည်မှု အေဂျင့် ဝန်ဆောင်မှုသို့ ချိတ်တွဲခွင့်ကို ပေးသည်။"</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"အဆင့်မြှင့်ခြင်းနဲ့ ပြန်လည် ထိန်းသိမ်းခြင်း များနှင့် ဆက်ဆံစေခြင်း"</string>
     <string name="permdesc_recovery" msgid="8511774533266359571">"အပလီကေးရှင်းအား စစ်စတန်အား ပြန်လည် ကယ်ဆယ်မှု နဲ့ အဆင့်မြှင့်ခြင်းများအား လုပ်ဆောင်ခွင့် ပေးခြင်း"</string>
     <string name="permlab_manageMediaProjection" msgid="1120495449419929218">"မီဒီယာ ပရိုဂျက် ချိတ်ဆက်မှုများကို စီမံကွပ်ကဲခြင်း"</string>
-    <string name="permdesc_manageMediaProjection" msgid="8053759147529492856">"အပလီကေးရှင်းအား မီဒီယာ ပရိုဂျက် ချိတ်ဆက်မှုများကို စီမံကွပ်ကဲခွင့် ပြုသည်။ ယင်း ချိတ်ဆက်မှုများ အတွင်းမှာ အပလီကေးရှင်း အတွက် ပြသမှု နှင့် အသံ အကြောင်းအရာများကို ဖမ်းယူရေး အခွင့်အလမ်းများကို စီမံပေးနိုင်သည်။ ပုံမှန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
+    <string name="permdesc_manageMediaProjection" msgid="8053759147529492856">"အပလီကေးရှင်းအား မီဒီယာ ပရိုဂျက် ချိတ်ဆက်မှုများကို စီမံကွပ်ကဲခွင့် ပြုသည်။ ယင်း ချိတ်ဆက်မှုများ အတွင်းမှာ အပလီကေးရှင်း အတွက် ပြသမှု နှင့် အသံ အကြောင်းအရာများကို ဖမ်းယူရေး အခွင့်အလမ်းများကို စီမံပေးနိုင်သည်။ ပုံမှန် appများ အတွက် ဘယ်တော့မှ မလိုအပ်နိုင်ပါ။"</string>
     <string name="permlab_readInstallSessions" msgid="6165432407628065939">"တပ်ဆင်ရေး ချိတ်ဆက်မှုများကို ဖတ်ရန်"</string>
-    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"အပလီကေးရှင်းအား တပ်ဆင်ရေး ချိတ်ဆက်မှုများကို ဖတ်ခွင့်ပြုသည်။ ၎င်းသည် ဖွင့်သုံးနေသည့် အထုပ်အား တပ်ဆင်မှုဆိုင်ရာ အသေးိစတ်များကို ကြည့်ရှုခွင့် ပြုသည်။"</string>
+    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"အပလီကေးရှင်းအား တပ်ဆင်ရေး ချိတ်ဆက်မှုများကို ဖတ်ခွင့်ပြုသည်။ ၎င်းသည် ဖွင့်သုံးနေသည့် အထုပ်အား တပ်ဆင်မှုဆိုင်ရာ အသေးိစတ်များကို ကြည့်ရှုခွင့် ပြုသည်။"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ချုံ့ချဲ့မှုကို ထိန်းချုပ်ရန် အတွက် နှစ်ကြိမ် ထိပါ"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ဝဒ်ဂျက်ထည့်လို့ မရပါ"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"သွားပါ"</string>
@@ -1487,9 +1487,9 @@
     <string name="ime_action_previous" msgid="1443550039250105948">"အနောက်သို့"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"လုပ်ဆောင်ချက်"</string>
     <string name="dial_number_using" msgid="5789176425167573586">\n"အား အသုံးပြု၍ <xliff:g id="NUMBER">%s</xliff:g>နံပါတ်ခေါ်ဆိုပါ"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">\n"အား အသုံးပြု၍<xliff:g id="NUMBER">%s</xliff:g>ဆက်သွယ်မည့်သူများအား ဖန်တီးခြင်း"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"အောက်ပါထဲက app တစ်ခု သို့မဟုတ် ပိုလျက် သင်၏ အကောင့်ကို၊ ယခု နှင့် အနာဂတ်မှာ ရယူအသုံးချရန် ခွင့်ပြုချက်ကို တောင်းထားသည်။"</string>
-    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ဤတောင်းခံမှုအားခွင့်ပြုမည်လား"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">\n"အား အသုံးပြု၍<xliff:g id="NUMBER">%s</xliff:g>ဆက်သွယ်မည့်သူများအား ဖန်တီးခြင်း"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"အောက်ပါထဲက app တစ်ခု သို့မဟုတ် ပိုလျက် သင်၏ အကောင့်ကို၊ ယခု နှင့် အနာဂတ်မှာ ရယူအသုံးချရန် ခွင့်ပြုချက်ကို တောင်းထားသည်။"</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ဤတောင်းခံမှုအားခွင့်ပြုမည်လား"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"သုံးစွဲခွင့် တောင်းဆိုရန်"</string>
     <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
     <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
@@ -1497,7 +1497,7 @@
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"အကောင့် <xliff:g id="ACCOUNT">%s</xliff:g> အတွက် \n ခွင့်ပြုချက် တောင်းခံထားပြီး"</string>
     <string name="forward_intent_to_owner" msgid="1207197447013960896">"သင်သည် ဒီappကို သင့်အလုပ်ပရိုဖိုင် ပြင်ပတွင် အသုံးပြုနေ၏"</string>
     <string name="forward_intent_to_work" msgid="621480743856004612">"သင်သည် ဒီappကို သင်၏ အလုပ် ပရိုဖိုင် ထဲမှာ အသုံးပြုနေသည်"</string>
-    <string name="input_method_binding_label" msgid="1283557179944992649">"ထည့်သွင်းရန်နည်းလမ်း"</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"ထည့်သွင်းရန်နည်းလမ်း"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"ထပ်တူ ကိုက်ညီခြင်း"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"အသုံးပြုခွင့်"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"နောက်ခံ"</string>
@@ -1513,12 +1513,12 @@
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"အမြဲတမ်းဖွင့်ထား VPN အမှား"</string>
     <string name="vpn_lockdown_config" msgid="6415899150671537970">"ပြင်ဆင်ရန် ထိလိုက်ပါ"</string>
     <string name="upload_file" msgid="2897957172366730416">"ဖိုင်ရွေးချယ်ရန်"</string>
-    <string name="no_file_chosen" msgid="6363648562170759465">"မည်သည့်ဖိုင်ကိုမှမရွေးပါ"</string>
+    <string name="no_file_chosen" msgid="6363648562170759465">"မည်သည့်ဖိုင်ကိုမှမရွေးပါ"</string>
     <string name="reset" msgid="2448168080964209908">"ပြန်လည်စတင်စေရန်"</string>
-    <string name="submit" msgid="1602335572089911941">"တင်​ပြရန်​"</string>
+    <string name="submit" msgid="1602335572089911941">"တင်​ပြရန်"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"ကားထဲတွင်အသုံးပြုနိုင်သောစနစ် ရရှိနိုင်သည်"</string>
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ကားပေါ်ရောက် အခြေအနေမှ ထွက်ရန် ထိလိုက်ပါ"</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"အပြင်အဆင်ပြုလုပ်ရန် ပိုမိုသိနားလည်စေရန် တို့ထိပါ။"</string>
     <string name="back_button_label" msgid="2300470004503343439">"နောက်သို့"</string>
     <string name="next_button_label" msgid="1080555104677992408">"နောက်"</string>
@@ -1553,14 +1553,14 @@
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)မှတောင်းခံသည်"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"ဟုတ်ကဲ့"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"မဟုတ်ပါ"</string>
-    <string name="sync_too_many_deletes" msgid="5296321850662746890">"ပယ်ဖျက်မည့်ကန့်သတ်နှုန်းကျော်လွန်သည်"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"ပယ်ဖျက်မည့်ကန့်သတ်နှုန်းကျော်လွန်သည်"</string>
     <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>၊  account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> အတွက် စုစုပေါင်း <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> အရာဖျက်ထားပါသည်။ သင်ဘာလုပ်ချင်ပါလဲ?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"ဤအရာများကိုဖျက်ပါ"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"ဖျက်ပီးသည်များကို ပယ်ဖျက်ရန်"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"လက်ရှိ ဘာမှမလုပ်ရန်"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"အကောင့် တစ်ခု ရွေးပါ"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"အကောင့် ထပ်ဖြည့်ပါ"</string>
-    <string name="add_account_button_label" msgid="3611982894853435874">"အကောင့်ထပ်ထည့်ရန်"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"အကောင့် တစ်ခု ရွေးပါ"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"အကောင့် ထပ်ဖြည့်ပါ"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"အကောင့်ထပ်ထည့်ရန်"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"တိုးရန်"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"လျှော့ရန်"</string>
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ကြာကြာ ဖိ ကိုင်ထားပါ"</string>
@@ -1580,15 +1580,15 @@
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Altခလုတ်"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ပယ်ဖျက်ရန်ခလုတ်"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ဖျက်ရန်ခလုတ်"</string>
-    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ပြီးဆုံးသည့်ခလုတ်"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ပြီးဆုံးသည့်ခလုတ်"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"စနစ်ပြောင်းခြင်းခလုတ်"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shiftခလုတ်"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enterခလုတ်"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"app တစ်ခုကို ရွေးရန်"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ကို စတင်လို့ မရပါ"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"မျှဝေဖို့ ရွေးပါ"</string>
-    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>နှင့် မျှဝေပါမည်"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"ဆွဲယူနိုင်သည့် လက်ကိုင်။ ထိပါ &amp; ကိုင်ထားပါ။"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>နှင့် မျှဝေပါမည်"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"ဆွဲယူနိုင်သည့် လက်ကိုင်။ ထိပါ &amp; ကိုင်ထားပါ။"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"သော့ဖွင့်ရန် ပွတ်ဆွဲပါ"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"စကားဝှက်ပြောဆိုမှုကို ကြားနိုင်ရန် မိုက်ခွက်ပါနားကြပ် တပ်ပြီး နားထောင်ပါ"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ဒေါ့"</string>
@@ -1599,21 +1599,21 @@
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s ၊ %2$s ၊ %3$s"</string>
     <string name="storage_internal" msgid="4891916833657929263">"စက်တွင်း သိုလှောင်ထားမှု"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ကဒ်"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USBဖြင့် သိမ်းဆည်း"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USBဖြင့် သိမ်းဆည်း"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"ပြင်ဆင်ရန်"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"ဒေတာအသုံးပြုမှုသတိပေးချက်"</string>
     <string name="data_usage_warning_body" msgid="2814673551471969954">"ဆက်တင်နှင့်သုံးစွဲမှုကြည့်ရန်ထိပါ"</string>
-    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
-    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
-    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"ဆယ်လူလာ ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
-    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"ကြိုးမဲ့ ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
+    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
+    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
+    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"ဆယ်လူလာ ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"ကြိုးမဲ့ ဒေတာ ကန့်သတ်ချက် ပြည့်မီသွားပြီ"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"ကျန် စက်ဝန်း အတွက် ဒေတာကို ဆိုင်းငံ့ထား"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"သတ်မှတ်ထားသော2G-3Gဒေတာအားကျော်လွန်နေသည်"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"သတ်မှတ်ထားသော4Gဒေတာအားကျော်လွန်နေသည်"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"ဆယ်လူလာ ကန့်သတ်ချက် ကျော်လွန်သွားပြီ"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"ဆယ်လူလာ ကန့်သတ်ချက် ကျော်လွန်သွားပြီ"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"သတ်မှတ်ဝိုင်ဖိုင်ဒေတာထက်ကျော်နေ"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"သက်မှတ်နှုန်းထက် <xliff:g id="SIZE">%s</xliff:g> ကျော်နေပါသည်"</string>
-    <string name="data_usage_restricted_title" msgid="5965157361036321914">"နောက်ခံဒေတာ ကန့်သတ်ထားသည်"</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"နောက်ခံဒေတာ ကန့်သတ်ထားသည်"</string>
     <string name="data_usage_restricted_body" msgid="6741521330997452990">"ကန့်သတ်ထားမှု ဖျက်ရန် ထိလိုက်ပါ"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"လုံခြံုမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ဤအသိအမှတ်ပြုလက်မှတ်မှာ တရားဝင်သည်"</string>
@@ -1631,7 +1631,7 @@
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 လက်ပွေ"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"အားလုံးကို ကြည့်ရန်"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"လှုပ်ရှားမှုကို ရွေးရန်"</string>
-    <string name="share_action_provider_share_with" msgid="5247684435979149216">"...နှင့် မျှဝေရန်"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"...နှင့် မျှဝေရန်"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"ပေးပို့နေစဉ်…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ဘရောက်ဇာ ဖွင့်မည်လား။"</string>
@@ -1695,17 +1695,17 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"သင်သည် စကားဝှက်ကို  <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားရိုက်ပြီးပါပြီ။ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ ပြန်လည်ကြိုးစားပါ"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"သင် ပုံစံဆွဲ သော့ဖွင့်ခြင်းကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ်မြောက် မအောင်မြင်ပါ။ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်လည် ကြိုးစားပါ"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"သင့်တက်ဘလက်အား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER_0">%d</xliff:g>  ကြိုးစားပြီးပါပြီ။ နောက်ထပ်  <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မအောင်မြင်ပါက၊ တက်ဘလက်က စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားမည်ဖြစ်ပြီး ဒေတာအားလုံး ဆုံးရှုံးသွားပါမည်။"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"သင့်ဖုန်းအား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER_0">%d</xliff:g> ကြိုးစားပြီးပါပြီ။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မအောင်မြင်ပါက၊ ဖုန်းက စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားမည်ဖြစ်ပြီး ဒေတာအားလုံး ဆုံးရှုံးသွားပါမည်။"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"သင့်တက်ဘလက် အား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER">%d</xliff:g> ကြိုးစားပြီးပါပြီ။ တက်ဘလက်က စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားပါတော့မည်။"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်၏။"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်၏။"</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"သင့်ဖုန်းအား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER">%d</xliff:g>  ကြိုးစားပြီးပါပြီ။ ဖုန်းက စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားပါတော့မည်။"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"သင် ပုံဖော်၍သော့ဖွင့်ခြင်းကို  <xliff:g id="NUMBER_0">%d</xliff:g> အကြိမ် မှန်ကန်စွာ မပြုလုပ်နိုင်ပါ။  နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မမှန်ကန်ပါက သင့်တက်ဘလက်အား အီးမေးလ်အသုံးပြု၍ သော့ဖွင့်ရန် တောင်းဆိုပါလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်လည် ကြိုးစားပါ"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ပုံဖော်၍ သော့ဖွင့်ခြင်းအား သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားဆွဲပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် အီးမေးအက​ောင့်အားသုံးလျက် သော့ဖွင့်ရန် ပြောလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ပုံဖော်၍ သော့ဖွင့်ခြင်းအား သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားဆွဲပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် အီးမေးအက​ောင့်အားသုံးလျက် သော့ဖွင့်ရန် ပြောလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"သင် ပုံဖော်၍သော့ဖွင့်ခြင်းကို <xliff:g id="NUMBER_0">%d</xliff:g> အကြိမ် မှန်ကန်စွာ မပြုလုပ်နိုင်ပါ။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မမှန်ကန်ပါက သင့်ဖုန်းအား အီးမေးလ်အသုံးပြု၍ သော့ဖွင့်ရန် တောင်းဆိုပါလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်လည် ကြိုးစားပါ"</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ဖယ်ရှားရန်"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"လက်နှစ်ချောင်းကို ထိကိုင်ထားခြင်းဖြင့် သုံးစွဲနိုင်မှုကို ခွင့်ပြုပါ"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"သုံးစွဲခွင့် ကို ဖွင့်ထားသည်"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"အသုံးပြုခွင့် ဖျက်လိုက်သည်"</string>
@@ -1713,7 +1713,7 @@
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေ…"</string>
     <string name="owner_name" msgid="2716755460376028154">"ပိုင်ရှင်"</string>
     <string name="error_message_title" msgid="4510373083082500195">"အမှား"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ဒီအပြောင်းအလဲမျိုးကို သင့် စီမံအုပ်ချုပ်သူမှ ခွင့်မပြုပါ"</string>
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"ဒီအပြောင်းအလဲမျိုးကို သင့် စီမံအုပ်ချုပ်သူမှ ခွင့်မပြုပါ"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ဤလုပ်ဆောင်ချက်ကို ပြုလုပ်ပေးမည့် အပလီကေးရှင်း မရှိပါ။"</string>
     <string name="revoke" msgid="5404479185228271586">"ထားတော့"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"အိုက်အက်စ်အို အေ ဝ"</string>
@@ -1832,16 +1832,16 @@
     <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ခုရွေးချယ်ထားပြီး"</string>
     <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ကို ဖျက်ပြီးပါပြီ"</string>
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"အလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7570091317001980053">"ဒီမျက်နှာပြင် ပင်ထိုးမှုကို ဖြုတ်ရန်၊ နောက်သို့ နှင့် ခြုံကြည့်မှု ခလုတ်များကို တစ်ချိန်တည်း ထိကိုင်ထားပါ။"</string>
-    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ဒီမျက်နှာပြင် ပင်ထိုးမှုကို ဖြုတ်ရန် ခြုံကြည့်မှု ခလုတ်ကို ထိကိုင်ထားပါ။"</string>
-    <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"မျက်နှာပြင်ကို ပင်ထိုးထားသည်။ ပင်ထိုးထားမှု ဖြုတ်ခြင်းကို သင့် အဖွဲ့အစည်းက ခွင့် မပြုပါ။"</string>
+    <string name="lock_to_app_toast" msgid="7570091317001980053">"ဒီမျက်နှာပြင် ပင်ထိုးမှုကို ဖြုတ်ရန်၊ နောက်သို့ နှင့် ခြုံကြည့်မှု ခလုတ်များကို တစ်ချိန်တည်း ထိကိုင်ထားပါ။"</string>
+    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ဒီမျက်နှာပြင် ပင်ထိုးမှုကို ဖြုတ်ရန် ခြုံကြည့်မှု ခလုတ်ကို ထိကိုင်ထားပါ။"</string>
+    <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"မျက်နှာပြင်ကို ပင်ထိုးထားသည်။ ပင်ထိုးထားမှု ဖြုတ်ခြင်းကို သင့် အဖွဲ့အစည်းက ခွင့် မပြုပါ။"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"မျက်နှာပြင်ကို ပင်ထိုးထား"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"မျက်နှာပြင် ပင်ထိုးမှု ဖြတ်လိုက်ပြီ"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ပင်မဖြုတ်မီမှာ PIN ကို မေးကြည့်ရန်"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string>
-    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို  လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေး၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string>
-    <string name="downtime_condition_summary" msgid="8761776337475705749">"သင်၏ စက်ရပ်ချိန် <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> မှာ ပြီးဆုံးသည့် အထိ။"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ပင်မဖြုတ်မီမှာ PIN ကို မေးကြည့်ရန်"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို  လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေး၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string>
+    <string name="downtime_condition_summary" msgid="8761776337475705749">"သင်၏ စက်ရပ်ချိန် <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> မှာ ပြီးဆုံးသည့် အထိ။"</string>
     <string name="downtime_condition_line_one" msgid="8762708714645352010">"သင့်ကျချိန်အဆုံးအထိ"</string>
   <plurals name="zen_mode_duration_minutes_summary">
     <item quantity="one" msgid="3177683545388923234">"တစ်မိနစ်ကြာ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>အထိ)"</item>
@@ -1858,13 +1858,13 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
-    <string name="zen_mode_forever" msgid="4316804956488785559">"အကန့်အသတ်မရှိစွာ"</string>
+    <string name="zen_mode_forever" msgid="4316804956488785559">"အကန့်အသတ်မရှိစွာ"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
     <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"နောက်ထပ် <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ၌နိုးစက်အထိ"</string>
     <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"နောက်ထပ်နိုးစက်အထိ"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> အသံပိတ်သည်"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
-    <string name="system_error_manufacturer" msgid="8086872414744210668">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"DIAL တောင်းဆိုချက်အရ USSD တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"SS တောင်းဆိုချက် အရ USSD တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
     <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD တောင်းဆိုချက် အသစ်အရ USSD တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d0c612d..0376a5d 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -293,6 +293,7 @@
             }
 
         See src/com/android/settings/TetherSettings.java for more details.
+        For ui-less/periodic recheck support see config_mobile_hotspot_provision_app_no_ui
         -->
     <!-- The first element is the package name and the second element is the class name
          of the provisioning app -->
@@ -303,8 +304,42 @@
     -->
     </string-array>
 
+    <!-- If the mobile hotspot feature requires provisioning, an action can be provided
+         that will be broadcast in non-ui cases for checking the provisioning status.
+
+         A second broadcast, action defined by config_mobile_hotspot_provision_response,
+         will be sent back to notify if provisioning succeeded or not.  The response will
+         match that of the activity in config_mobile_hotspot_provision_app, but instead
+         contained within the int extra "EntitlementResult".
+
+         Example Usage:
+         String provisionAction = getString(R.string.config_mobile_hotspot_provision_check);
+         sendBroadcast(new Intent(provisionAction));
+
+         public void onReceive(Context context, Intent intent) {
+             String provisionResponse =
+                    getString(R.string.config_mobile_hotspot_provision_response);
+             if (provisionResponse.equals(intent.getAction())
+                    && intent.getIntExtra("EntitlementResult") == Activity.RESULT_OK) {
+                 //Mobile hotspot provisioning successful
+             } else {
+                 //Mobile hotspot provisioning failed
+             }
+         }
+        -->
+    <string translatable="false" name="config_mobile_hotspot_provision_app_no_ui"></string>
+    <!-- Sent in response to a provisioning check. The caller must hold the
+         permission android.permission.CONNECTIVITY_INTERNAL for Settings to
+         receive this response.
+
+         See config_mobile_hotspot_provision_response
+         -->
+    <string translatable="false" name="config_mobile_hotspot_provision_response"></string>
+    <!-- Number of hours between each background provisioning call -->
+    <integer translatable="false" name="config_mobile_hotspot_provision_check_period">24</integer>
+
     <!-- Activity name to enable wifi tethering after provisioning app succeeds -->
-    <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.EnableWifiTether</string>
+    <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.TetherService</string>
 
     <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
     <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
@@ -425,6 +460,12 @@
     <!-- Integer indicating minimum blacklisting delay of a wofo configuration due to connectin or auth errors -->
     <integer translatable="false" name="config_wifi_framework_network_black_list_min_time_milli">120000</integer>
 
+    <!-- Integer indicating RSSI boost given to current network -->
+    <integer translatable="false" name="config_wifi_framework_current_network_boost">25</integer>
+
+    <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 -->
+    <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer>
+
     <!-- Boolean indicating associated scan are allowed -->
     <bool translatable="false" name="config_wifi_framework_enable_associated_autojoin_scan">true</bool>
 
@@ -1830,6 +1871,9 @@
          provisioning, availability etc -->
     <bool name="config_carrier_volte_available">false</bool>
 
+    <!-- Flag specifying whether VoLTE availability is based on provisioning -->
+    <bool name="config_carrier_volte_provisioned">false</bool>
+
     <!-- Flag specifying whether VT is available on device -->
     <bool name="config_device_vt_available">false</bool>
 
@@ -1969,7 +2013,9 @@
     <!-- An array of CDMA roaming indicators which means international roaming -->
     <integer-array translatable="false" name="config_cdma_international_roaming_indicators" />
 
-
     <!-- set the system language as value of EF LI/EF PL -->
     <bool name="config_use_sim_language_file">true</bool>
+
+    <!-- Use ERI text for network name on CDMA LTE -->
+    <bool name="config_LTE_eri_for_network_name">true</bool>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index bdb0324..e1e1ffed 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -56,6 +56,7 @@
     <dimen name="action_bar_overflow_padding_start_material">6dp</dimen>
     <!-- Padding to add to the end of the overflow action button. -->
     <dimen name="action_bar_overflow_padding_end_material">10dp</dimen>
+    <dimen name="action_bar_elevation_material">4dp</dimen>
 
     <dimen name="action_button_min_width_overflow_material">36dp</dimen>
     <dimen name="action_button_min_width_material">48dp</dimen>
@@ -87,9 +88,9 @@
     <dimen name="floating_window_margin_bottom">32dp</dimen>
 
     <!-- Elevation when button is pressed -->
-    <dimen name="button_elevation_material">4dp</dimen>
+    <dimen name="button_elevation_material">2dp</dimen>
     <!-- Z translation to apply when button is pressed -->
-    <dimen name="button_pressed_z_material">2dp</dimen>
+    <dimen name="button_pressed_z_material">4dp</dimen>
     <!-- Default insets (outer padding) around buttons -->
     <dimen name="button_inset_vertical_material">6dp</dimen>
     <dimen name="button_inset_horizontal_material">@dimen/control_inset_material</dimen>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index d3d6d70..6220a1b 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -917,7 +917,7 @@
         <item name="gravity">center_vertical</item>
         <item name="contentInsetStart">@dimen/action_bar_content_inset_material</item>
         <item name="contentInsetEnd">@dimen/action_bar_content_inset_material</item>
-        <item name="elevation">8dp</item>
+        <item name="elevation">@dimen/action_bar_elevation_material</item>
         <item name="popupTheme">?attr/actionBarPopupTheme</item>
     </style>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9845096..6661290 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -324,6 +324,8 @@
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_5" />
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_24" />
   <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_5" />
+  <java-symbol type="integer" name="config_wifi_framework_scan_result_rssi_level_patchup_value" />
+  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
   <java-symbol type="string"  name="config_wifi_random_mac_oui" />
 
   <java-symbol type="bool" name="editable_voicemailnumber" />
@@ -338,6 +340,7 @@
   <java-symbol type="integer" name="config_wifi_framework_max_connection_errors_to_blacklist" />
   <java-symbol type="integer" name="config_wifi_framework_max_auth_errors_to_blacklist" />
   <java-symbol type="integer" name="config_wifi_framework_network_black_list_min_time_milli" />
+  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
@@ -1877,6 +1880,9 @@
 
   <!-- From Settings -->
   <java-symbol type="array" name="config_mobile_hotspot_provision_app" />
+  <java-symbol type="string" name="config_mobile_hotspot_provision_app_no_ui" />
+  <java-symbol type="string" name="config_mobile_hotspot_provision_response" />
+  <java-symbol type="integer" name="config_mobile_hotspot_provision_check_period" />
   <java-symbol type="string" name="config_wifi_tether_enable" />
   <java-symbol type="bool" name="config_intrusiveNotificationLed" />
   <java-symbol type="dimen" name="preference_fragment_padding_bottom" />
@@ -2079,6 +2085,7 @@
   <java-symbol type="bool" name="imsServiceAllowTurnOff" />
   <java-symbol type="bool" name="config_device_volte_available" />
   <java-symbol type="bool" name="config_carrier_volte_available" />
+  <java-symbol type="bool" name="config_carrier_volte_provisioned" />
   <java-symbol type="bool" name="config_device_vt_available" />
   <java-symbol type="bool" name="config_carrier_vt_available" />
   <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
@@ -2145,4 +2152,5 @@
   <java-symbol type="string" name="kg_text_message_separator" />
 
   <java-symbol type="bool" name="config_use_sim_language_file" />
+  <java-symbol type="bool" name="config_LTE_eri_for_network_name" />
 </resources>
diff --git a/docs/html/about/start.jd b/docs/html/about/start.jd
index 727c975..4658141 100644
--- a/docs/html/about/start.jd
+++ b/docs/html/about/start.jd
@@ -5,12 +5,13 @@
 @jd:body
 
 <p>Everything you need to start developing apps for Android is available here on
-developer.android.com. You'll find everything from the developer SDK, API documentation, and design
-guidelines, to information about the current device landscape and how you can distribute and
-monetize your app.</p>
+<em>developer.android.com</em>. You'll find everything from the API documentation
+and design guidelines, to information about the current device landscape and how you can distribute
+and monetize your app.</p>
+
 
 <p>No two apps are built in the same way, but we've structured the information you need to build an
-app into the following three sections that represent the general order for app development. 
+app into the following three sections that represent the general order for app development.
 
 
 <style>
@@ -32,7 +33,7 @@
 should pause to focus on how a user will <em>interact</em> with it. Your design should be sleek,
 simple, powerful, and tailored to the Android experience.</p>
 
-<p>So whether you're a one-man shop or a large team, you should study the <a
+<p>So whether you're creating an app alone or you're part of a team, study the <a
 href="{@docRoot}design/index.html">Design</a> guidelines first.</p>
 </div>
 
@@ -59,6 +60,10 @@
 available in the <a href="{@docRoot}distribute/index.html">Distribute</a> section.</p>
 </div>
 
+<p style="clear:both;height:0">&nbsp;</p>
 
-<p style="clear:both">Now that you know what's available, get started by installing the <a
-href="{@docRoot}sdk/index.html">Android SDK</a>.</p>
\ No newline at end of file
+<h2>Go!</h2>
+<p>Get started by installing <a
+href="{@docRoot}sdk/index.html">Android Studio</a>&mdash;the official IDE for Android development,
+which includes the Android SDK tools. Then when you're ready to begin coding, follow the training
+for <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.</p>
\ No newline at end of file
diff --git a/docs/html/about/versions/android-5.0-changes.jd b/docs/html/about/versions/android-5.0-changes.jd
index f12e83c..3de5c3c 100644
--- a/docs/html/about/versions/android-5.0-changes.jd
+++ b/docs/html/about/versions/android-5.0-changes.jd
@@ -1,9 +1,10 @@
-page.title=Android 5.0 Changes
+page.title=Android 5.0 Behavior Changes
 excludeFromSuggestions=true
 sdk.platform.version=5.0
 sdk.platform.apiLevel=21
 @jd:body
 
+<!-- video box -->
 
 <div id="qv-wrapper">
 <div id="qv">
@@ -20,8 +21,16 @@
   <li><a href="#Power"><a href="#BehaviorWebView">WebView</a></a></li>
   <li><a href="#custom_permissions">Custom Permissions</a></li>
   <li><a href="#ssl">TLS/SSL Configuration</a></li>
+  <li><a href="#managed_profiles">Support for Managed Profiles</a></li>
 </ol>
 
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY">
+<div>
+    <h3>Video</h3>
+    <p>Notifications</p>
+</div>
+</a>
+
 <h2>API Differences</h2>
 <ol>
 <li><a href="{@docRoot}sdk/api_diff/21/changes.html">API level 20 to 21 &raquo;</a> </li>
@@ -40,9 +49,8 @@
 </div>
 
 <p>API Level: {@sdkPlatformApiLevel}</p>
-<p>Along with new features and capabilities, Android 5.0 includes a variety of changes
-API changes,
-behavior changes, system enhancements, and bug fixes. This document highlights
+<p>Along with new features and capabilities, Android 5.0 includes a variety of
+system changes and API behavior changes. This document highlights
 some of the key changes that you should be understand and account for in your apps.</p>
 
 <p>If you have previously published an app for Android, be aware that your app
@@ -296,8 +304,8 @@
 
 <p>
   Android 5.0 includes a behavior change to ensure
-  that only one app can define a given custom permission, unless signed with the 
-  same key as other apps defining the permission. 
+  that only one app can define a given custom permission, unless signed with the
+  same key as other apps defining the permission.
 </p>
 
 <h3>
@@ -316,7 +324,7 @@
 <p>
   In Android 4.4 and earlier, users were able to install multiple such
   apps on a given device, although the system assigned the protection level
-  specified by the first-installed app. 
+  specified by the first-installed app.
 </p>
 
 <p>
@@ -522,4 +530,64 @@
   communicate with the server. The factory should be designed to create
   SSLSocket instances with only those protocols enabled which are correctly
   supported by the server.
-</p>
\ No newline at end of file
+</p>
+
+<h2 id="managed_profiles">Support for Managed Profiles</h2>
+
+<p>
+  Device administrators can add a <em>managed profile</em> to a device. This
+  profile is owned by the administrator, giving the administrator control
+  over the managed profile while leaving the user's personal profile, and its
+  storage space, under the user's control.
+  This change can affect the behavior of your existing app in
+  the following ways.</p>
+
+<h3 id="mg_profile_intents">Handling intents</h3>
+
+<p>Device administrators can restrict access to system applications from the
+managed profile. In this case, if an app fires an intent from the managed
+profile that would ordinarily be handled by that application, and there is no
+suitable handler for the intent on the managed profile,
+the intent causes an exception. For example, the
+device administrator can restrict apps on the managed profile from accessing
+the system's camera application. If your app is running on the managed profile
+and calls {@link
+android.app.Activity#startActivityForResult startActivityForResult()} for {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+MediaStore.ACTION_IMAGE_CAPTURE}, and there is no app on the managed profile
+that can handle the intent, this results in an {@link
+android.content.ActivityNotFoundException}.</p>
+
+<p>You can prevent this by checking
+that there is at least one handler for any intent
+before firing it. To check for a valid handler, call {@link
+android.content.Intent#resolveActivity Intent.resolveActivity()}. You can see
+an example of this being done in <a
+href="{@docRoot}training/camera/photobasics.html#TaskCaptureIntent">Take Photos
+Simply: Take a Photo with the Camera App</a>.</p>
+
+<h3 id="mp_profile_file_sharing">Sharing files across profiles</h3>
+
+<p>Each profile has its own file storage. Since a file URI refers to a specific
+location in the file storage, this means that a file URI that is valid on one
+profile is not valid on the other one. This is not ordinarily a problem for an
+app, which usually just accesses the files it creates. However, if an app
+attaches a file to an intent, it is not safe to attach a file URI, since in some
+circumstances, the intent might be handled on the other profile.
+For example, a device administrator might specify that image capture events
+should be handled by the camera app on the personal profile. If the intent is
+fired by an app on the managed profile, the camera needs to be able to write the
+image to a location where the managed profile's apps can read it.</p>
+
+<p>To be safe, when
+you need to attach a file to an intent that might cross from one profile to the
+other, you should create and use a <em>content URI</em> for the file. For more
+information about sharing files with content URIs, see <a
+href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>.
+For example, the device administrator might whitelist {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} to be
+handled by the camera in the personal profile. The firing intent's {@link
+android.provider.MediaStore#EXTRA_OUTPUT EXTRA_OUTPUT} should contain a content
+URI specifying where the photo should be stored. The camera app can write the
+image to the location specified by that URI, and the app that fired the intent
+would be able to read that file, even if the app is on the other profile. </p>
diff --git a/docs/html/design/design_toc.cs b/docs/html/design/design_toc.cs
index 2cbdacd..63f5cad 100644
--- a/docs/html/design/design_toc.cs
+++ b/docs/html/design/design_toc.cs
@@ -26,6 +26,7 @@
           <li><a href="<?cs var:toroot ?>design/wear/context.html">Context Awareness</a></li>
           <li><a href="<?cs var:toroot ?>design/wear/patterns.html">UI Patterns</a></li>
           <li><a href="<?cs var:toroot ?>design/wear/style.html">Style</a></li>
+          <li><a href="<?cs var:toroot ?>design/wear/watchfaces.html">Watch Faces</a></li>
         </ul>
       </li>
       <li class="nav-section">
@@ -106,4 +107,4 @@
     <div class="nav-section-header empty"><a href="<?cs var:toroot ?>design/videos/index.html">Videos</a></div>
   </li>
 
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index a073428..16d61e7 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -137,7 +137,84 @@
 </div>
 
 
+<div class="layout-content-row">
+  <div class="layout-content-col span-5">
+  <h4>Watch faces UI toolkit</h4>
+<p>Detailed specifications and measurements for the the background canvas, notification cards, and
+system indicators.
+</p>
 
+  </div>
+  <div class="layout-content-col span-4">
+
+    <img src="{@docRoot}design/media/downloads_wear_DesignSpec_Icon.png" width="220">
+
+  </div>
+  <div class="layout-content-col span-4">
+  <a class="download-button"  onClick="ga('send', 'event', 'Design', 'Download', 'Wear Watch Face Specifications');"
+    href="{@docRoot}downloads/design/AndroidWear_DesignSpec_11.13.pdf">PDF Toolkit</a>
+  </div>
+</div>
+
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-5">
+  <h4>Slide watch face</h4>
+<p>Example of a watch face design in AI format.
+</p>
+
+  </div>
+  <div class="layout-content-col span-4">
+
+    <img src="{@docRoot}design/media/downloads_wear_Slide_Ai_Icon.png" width="150"
+         style="width:150px;margin:0 auto;display:block">
+
+  </div>
+  <div class="layout-content-col span-4">
+  <a class="download-button"  onClick="ga('send', 'event', 'Design', 'Download', 'Wear Watch Face Example');"
+    href="{@docRoot}downloads/design/Slide.ai">Adobe&reg; Illustrator&reg; Design</a>
+  </div>
+</div>
+
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-5">
+  <h4>Slide watch face specifications</h4>
+<p>Design specifications for the Slide watch face in PSD format.
+</p>
+
+  </div>
+  <div class="layout-content-col span-4">
+
+    <img src="{@docRoot}design/media/downloads_wear_Slide_Psd_Icon.png" width="150"
+         style="width:150px;margin:0 auto;display:block">
+
+  </div>
+  <div class="layout-content-col span-4">
+  <a class="download-button"  onClick="ga('send', 'event', 'Design', 'Download', 'Wear Watch Face Example Specifications');"
+    href="{@docRoot}downloads/design/Slide.psd">Adobe&reg; Photoshop&reg; Specifications</a>
+  </div>
+</div>
+
+
+<div class="layout-content-row">
+  <div class="layout-content-col span-5">
+  <h4>Watch face icon example</h4>
+<p>Template for creating watch face icons for the carousel on Android Wear devices.
+</p>
+
+  </div>
+  <div class="layout-content-col span-4">
+
+    <img src="{@docRoot}design/media/downloads_wear_Slide_IconExample.png" width="150"
+         style="width:150px;margin:0 auto;display:block">
+
+  </div>
+  <div class="layout-content-col span-4">
+  <a class="download-button"  onClick="ga('send', 'event', 'Design', 'Download', 'Wear Watch Face Example Specifications');"
+    href="{@docRoot}downloads/design/Slide_IconExample.psd">Adobe&reg; Photoshop&reg; Icon</a>
+  </div>
+</div>
 
 
 
diff --git a/docs/html/design/material/index.jd b/docs/html/design/material/index.jd
index db18a83..4d9a1a7 100644
--- a/docs/html/design/material/index.jd
+++ b/docs/html/design/material/index.jd
@@ -5,6 +5,40 @@
 
 @jd:body
 
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/material/index.html">
+  <div>
+    <h3>Developer Docs</h3>
+    <p>Creating Apps with Material Design</p>
+  </div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
+<div>
+    <h3>Video</h3>
+    <p>Introduction to Material Design</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
+<div>
+    <h3>Video</h3>
+    <p>Paper and Ink: The Materials that Matter</p>
+</div>
+</a>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
+<div>
+    <h3>Video</h3>
+    <p>Material Design in the Google I/O App</p>
+</div>
+</a>
+
+
+
 <p itemprop="description">Material design is a comprehensive guide for visual, motion, and
 interaction design across platforms and devices. Android now includes support for
 material design apps. To use material design in your Android apps, follow the guidelines defined
diff --git a/docs/html/design/media/downloads_wear_DesignSpec_Icon.png b/docs/html/design/media/downloads_wear_DesignSpec_Icon.png
new file mode 100644
index 0000000..c3d16133
--- /dev/null
+++ b/docs/html/design/media/downloads_wear_DesignSpec_Icon.png
Binary files differ
diff --git a/docs/html/design/media/downloads_wear_Slide_Ai_Icon.png b/docs/html/design/media/downloads_wear_Slide_Ai_Icon.png
new file mode 100644
index 0000000..69291b9
--- /dev/null
+++ b/docs/html/design/media/downloads_wear_Slide_Ai_Icon.png
Binary files differ
diff --git a/docs/html/design/media/downloads_wear_Slide_IconExample.png b/docs/html/design/media/downloads_wear_Slide_IconExample.png
new file mode 100644
index 0000000..227bd92
--- /dev/null
+++ b/docs/html/design/media/downloads_wear_Slide_IconExample.png
Binary files differ
diff --git a/docs/html/design/media/downloads_wear_Slide_Psd_Icon.png b/docs/html/design/media/downloads_wear_Slide_Psd_Icon.png
new file mode 100644
index 0000000..7b7d2ab
--- /dev/null
+++ b/docs/html/design/media/downloads_wear_Slide_Psd_Icon.png
Binary files differ
diff --git a/docs/html/design/media/wear/CardsRender_Build.png b/docs/html/design/media/wear/CardsRender_Build.png
new file mode 100644
index 0000000..cf1fbb8
--- /dev/null
+++ b/docs/html/design/media/wear/CardsRender_Build.png
Binary files differ
diff --git a/docs/html/design/media/wear/CompanionApp_Build.png b/docs/html/design/media/wear/CompanionApp_Build.png
new file mode 100644
index 0000000..ecf17ba2
--- /dev/null
+++ b/docs/html/design/media/wear/CompanionApp_Build.png
Binary files differ
diff --git a/docs/html/design/media/wear/DeviceSettings_Build.png b/docs/html/design/media/wear/DeviceSettings_Build.png
new file mode 100644
index 0000000..4bbf4b7
--- /dev/null
+++ b/docs/html/design/media/wear/DeviceSettings_Build.png
Binary files differ
diff --git a/docs/html/design/media/wear/Hotword_Cropped.png b/docs/html/design/media/wear/Hotword_Cropped.png
new file mode 100644
index 0000000..a947e1f
--- /dev/null
+++ b/docs/html/design/media/wear/Hotword_Cropped.png
Binary files differ
diff --git a/docs/html/design/media/wear/Indicators_Cropped.png b/docs/html/design/media/wear/Indicators_Cropped.png
new file mode 100644
index 0000000..9449c02
--- /dev/null
+++ b/docs/html/design/media/wear/Indicators_Cropped.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_1Bit.png b/docs/html/design/media/wear/Render_1Bit.png
new file mode 100644
index 0000000..53cbc07
--- /dev/null
+++ b/docs/html/design/media/wear/Render_1Bit.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Albumem.png b/docs/html/design/media/wear/Render_Albumem.png
new file mode 100644
index 0000000..054fe6b
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Albumem.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Ambient.png b/docs/html/design/media/wear/Render_Ambient.png
new file mode 100644
index 0000000..07e8c58
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Ambient.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Episode.png b/docs/html/design/media/wear/Render_Episode.png
new file mode 100644
index 0000000..2d545bb
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Episode.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Interactive.png b/docs/html/design/media/wear/Render_Interactive.png
new file mode 100644
index 0000000..a1e260b
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Interactive.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_LowBit.png b/docs/html/design/media/wear/Render_LowBit.png
new file mode 100644
index 0000000..83ac365
--- /dev/null
+++ b/docs/html/design/media/wear/Render_LowBit.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Next.png b/docs/html/design/media/wear/Render_Next.png
new file mode 100644
index 0000000..e080943
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Next.png
Binary files differ
diff --git a/docs/html/design/media/wear/Render_Saturn.png b/docs/html/design/media/wear/Render_Saturn.png
new file mode 100644
index 0000000..500018c
--- /dev/null
+++ b/docs/html/design/media/wear/Render_Saturn.png
Binary files differ
diff --git a/docs/html/design/media/wear/ScreenShapes_Invert.png b/docs/html/design/media/wear/ScreenShapes_Invert.png
new file mode 100644
index 0000000..bc6c135
--- /dev/null
+++ b/docs/html/design/media/wear/ScreenShapes_Invert.png
Binary files differ
diff --git a/docs/html/design/media/wear/ScreenShapes_Pyramids.png b/docs/html/design/media/wear/ScreenShapes_Pyramids.png
new file mode 100644
index 0000000..7d907ce
--- /dev/null
+++ b/docs/html/design/media/wear/ScreenShapes_Pyramids.png
Binary files differ
diff --git a/docs/html/design/media/wear/ScreenShapes_Rift.png b/docs/html/design/media/wear/ScreenShapes_Rift.png
new file mode 100644
index 0000000..9d32916
--- /dev/null
+++ b/docs/html/design/media/wear/ScreenShapes_Rift.png
Binary files differ
diff --git a/docs/html/design/wear/index.jd b/docs/html/design/wear/index.jd
index 104e154..c75723f 100644
--- a/docs/html/design/wear/index.jd
+++ b/docs/html/design/wear/index.jd
@@ -2,7 +2,6 @@
 @jd:body
 
 
-
 <p>Designing apps for wearable devices powered by Android Wear
 is substantially different than designing for phones or
 tablets: different strengths and weaknesses, different use cases, different ergonomics.
diff --git a/docs/html/design/wear/style.jd b/docs/html/design/wear/style.jd
index bb2e17f..abd3a9a 100644
--- a/docs/html/design/wear/style.jd
+++ b/docs/html/design/wear/style.jd
@@ -68,7 +68,7 @@
 
 <h2 id="KeepMinimum" style="clear:both">Keep Notifications to a Minimum</h2>
 
-<p>Don’t abuse the user’s attention. Active notifications (that is, those that cause the device to vibrate) should only be used in cases that are both timely and involve a contact, for example receiving a message from a friend. Non-urgent notifications should be silently added to the Context Stream. See also the general <a href={@docRoot}design/patterns/notifications.html">Android Notifications Guidelines</a>.</p>
+<p>Don’t abuse the user’s attention. Active notifications (that is, those that cause the device to vibrate) should only be used in cases that are both timely and involve a contact, for example receiving a message from a friend. Non-urgent notifications should be silently added to the Context Stream. See also the general <a href="{@docRoot}design/patterns/notifications.html">Android Notifications Guidelines</a>.</p>
 
 
 
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
new file mode 100644
index 0000000..1a4b1f9
--- /dev/null
+++ b/docs/html/design/wear/watchfaces.jd
@@ -0,0 +1,338 @@
+page.title=Watch Faces for Android Wear
+@jd:body
+
+
+<!-- developer docs box -->
+<a class="notice-developers right" href="{@docRoot}training/wearables/watch-faces/index.html"
+   style="clear:left;margin-bottom:90px">
+  <div>
+    <h3>Developer Docs</h3>
+    <p>Creating Watch Faces</p>
+  </div>
+</a>
+
+<p>Android Wear supports custom watch faces with designs that can show contextually relevant
+information to users. Designing a watch face requires a careful blending of data and visual
+elements that informs users without requiring close attention. Simple, attractive layouts that
+can adjust to different screen shapes and sizes, provide options for color and presentation, let
+users create a deeply personalized experience with the Wear device that fits them best. Watch
+faces exist as part of the Wear user interface, so it is important to provide interactive and
+ambient modes, and consider how system user interface elements will interact with your design.</p>
+
+<p>Follow the guidelines in this page to design your custom watch faces.</p>
+
+<!-- H2 creative vision -->
+<div style="float:right;margin-top:-100px;margin-bottom:20px;margin-left:20px">
+  <img src="{@docRoot}design/media/wear/Render_Next.png"
+       width="200" height="195" alt="" style="margin-right:5px"/><br/>
+  <img src="{@docRoot}design/media/wear/Render_Interactive.png"
+       width="200" height="195" alt="" style="margin-right:5px"/>
+</div>
+<h2 id="CreativeVision">Creative Vision</h2>
+
+<p>Creating a watch face for Android Wear is an exercise centered around visualizing time clearly.
+Android Wear devices provide a unique digital canvas to reimagine the ways in which we tell time.
+Android Wear also lets you integrate data on watch faces for a higher level of personalization and
+contextual relevance.</p>
+
+<p>These powerful new tools to create watch faces run the risk of overcomplicating a design. The
+most successful watch face designs leverage these advanced capabilities while delivering a
+singular, elegant expression of information.</p>
+
+<p>Glanceability is the single most important principle to consider when creating a watch face
+design. Your watch face designs should deliver a singular expression of time and related data.
+Experiment with bold, minimal, and expressive design directions that are highly readable at a
+distance.</p>
+
+
+
+<h2 id="SquareRound">Plan for Square and Round Devices</h2>
+
+<p>Android Wear devices come in different shapes and sizes. You will need to consider both
+square and round faces as well as different resolutions. Some concepts work better in a certain
+format, but a little planning will allow users to enjoy your watch face regardless of screen
+format.</p>
+
+<p>These guidelines help your concepts align across devices:</p>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-6">
+  <h3>Create flexible concepts</h3>
+  <p>Ideally, the visual functionality of the watch face works for both round and square
+  formats. In this example, the visual functionality of the watch face is flexible enough
+  to work well in either format without any adjustment. However, other design concepts require
+  different executions for square and round screens.</p>
+</div>
+<div class="layout-content-col span-7">
+  <img src="{@docRoot}design/media/wear/ScreenShapes_Invert.png" width="400"
+       height="221" alt="" style="margin-top:-30px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-6">
+  <h3>Use a common design language</h3>
+  <p>Try using a common set of colors, line weights, shading, and other design elements
+  to draw a visual connection between your square and round versions. By using similar color
+  palettes and a few consistent visual elements, the overall appearance of square and round
+  can be appropriately customized while still feeling like part of the same visual system.</p>
+</div>
+<div class="layout-content-col span-7">
+  <img src="{@docRoot}design/media/wear/ScreenShapes_Pyramids.png" width="400"
+       height="221" alt="" style="margin-top:-30px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-6">
+  <h3>Adjust for analog concepts</h3>
+  <p>Some of your concepts will naturally take the shape of an analog clock, like a center
+  dial with hour and minute hands. In this case, consider the corner areas that are exposed
+  when translating to a square format. Try extending and exploring this extra space.</p>
+</div>
+<div class="layout-content-col span-7">
+  <img src="{@docRoot}design/media/wear/ScreenShapes_Rift.png" width="400"
+       height="221" alt="" style="margin-top:-30px">
+</div>
+</div>
+
+
+
+<!-- H2: plan for all display modes -->
+<div style="float:right;margin-top:35px;margin-left:20px">
+  <img src="{@docRoot}design/media/wear/Render_Interactive.png"
+       width="200" height="195" alt="" style="margin-right:5px"/><br/>
+  <img src="{@docRoot}design/media/wear/Render_Ambient.png"
+     width="200" height="195" alt="" style="margin-right:5px"/>
+</div>
+<h2 id="DisplayModes">Plan for All Display Modes</h2>
+
+<p>Android Wear devices operate in two main modes: ambient and interactive. Your watch face
+designs should take these modes into account. Generally, if your watch face design looks great
+in ambient mode, it will look even better in interactive mode. The opposite is not always
+true.</p>
+
+<p>In ambient mode, the screen is only updated once every minute. Only show hours and minutes
+in ambient mode; do not show seconds in this mode.</p>
+
+<h3>Interactive mode</h3>
+<p>When the user moves their wrist to glance at their watch, the screen goes into interactive
+mode. Your design can use full color with fluid animation in this mode.</p>
+
+<h3>Ambient mode</h3>
+<p>Ambient mode helps the device conserve power. In this mode, the screen only displays shades
+of grey, black, and white. Your watch face is notified when the device switches to ambient mode,
+and you should thoughtfully design for it.</p>
+
+
+
+
+<h2 id="SpecialScreens">Optimize for Special Screens</h2>
+
+<p>Android Wear devices feature a variety of screen technologies, each with their own advantages
+and considerations. One important consideration when designing the ambient mode display for your
+watch face is how it affects battery life and screen burn-in on some screens.</p>
+
+<p>You can configure your watch face to display different ambient designs depending on the kind
+of screen available on the device. Consider the best design for your watch faces on all
+screens.</p>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>Low bit</h3>
+  <p>Pixels on some screens (including OLED and transflective LED) in ambient mode are either
+  "on" or "off", also known as "low-bit". When designing for low-bit ambient mode, use only black
+  and white, avoid grayscale colors, and disable antialiasing in your paint styles. Make sure to
+  test your design on devices with low-bit ambient mode.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Render_LowBit.png" width="200"
+       height="" alt="" style="margin-top:-30px;margin-left:13px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>Burn protection techniques</h3>
+  <p>When designing for OLED screens, you should consider power efficiency and the screen
+  burn-in effect. When these screens are in ambient mode, the system shifts the contents of
+  the screen periodically by a few pixels to avoid pixel burn-in. Do not use large blocks of
+  pixels in your ambient mode designs and keep 95% of the pixels black. Replace solid shapes in
+  your regular ambient mode designs with outlined shapes in burn-protected ambient mode. Also
+  replace filled images with pixel patterns. For analog watch face designs, hollow out the center
+  where the hands meet to avoid pixel burn-in in this mode.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Render_1Bit.png" width="200"
+       height="" alt="" style="margin-top:-30px;margin-left:13px">
+</div>
+</div>
+
+
+
+<h2 id="SystemUI">Accomodate System UI Elements</h2>
+
+<p>Your watch face designs should accommodate Android Wear UI elements. These elements give the
+user the status of the wearable and show notifications from services on the user's phone. Try
+to keep critical elements in your watch face designs from being obscured by the UI elements.</p>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>Cards</h3>
+<p>Cards are the notification system that bridges information between the wearable and a
+mobile device. Cards are also how most applications communicate with users. The user will be
+notified on the wearable about items such as emails and messages. As a watch face developer,
+you need to accommodate both large and small cards in your design. Your watch face can specify a
+preference for the card size, but users may override this setting. Users can also temporarily
+hide cards by swiping down on them.</p>
+<p>The peek card is the top card in the stream that is partially visible at the bottom of the
+screen. A variable peek card has a height that is determined by the amount of text within a given
+notification. A small peek card leaves more room for your design. Round faces with analog hands
+should have a small peek card. If the time signature is clearly visible above the maximum height
+of the variable peek card, you may choose to include the variable peek card. The benefit of a
+variable peek card is that it displays more notification information. Faces with information on
+the bottom half of the face should leverage the small peek card instead.</p>
+<p>The system notifies your watch face when the bounds of a peek card change, so you can
+rearrange the elements in your design if necessary.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/CardsRender_Build.png" width="200"
+       height="" alt="" style="margin-top:20px;margin-left:13px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>Indicators</h3>
+<p>Indicators tell the user the status of the wearable, such as charging and airplane mode.
+When designing a watch face, consider how the indicator will fall over the watch face.</p>
+<p>The indicators can be placed in several fixed locations on the wearable. If you have a
+large peek card, the indicators should go on the top or on the center of the screen. When you
+position the status icons or the hotword on the bottom of the screen, the system forces small
+peek cards. If the edge of the watch face contains strong visual elements, such as
+ticks or numbers, place the indicators on the center of the screen.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Indicators_Cropped.png" width="200"
+       height="" alt="" style="margin-top:0px;margin-left:13px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>The hotword</h3>
+<p>The hotword is the phrase "OK Google", which tells the user that they can interact with
+the watch using voice commands. When a user turns on the wearable, the hotword appears on
+the screen for a few seconds.</p>
+<p>The hotword no longer appears after the user says "OK Google" five times, so the placement of
+this element is not as critical. You should still avoid covering up elements of your
+watch face. Finally, background protection for the hotword and the indicators should be
+turned on unless your design is tailored to have these elements appear on top of them, for example
+using dark solid colors with no patterns.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Hotword_Cropped.png" width="200"
+       height="" alt="" style="margin-top:0px;margin-left:13px">
+</div>
+</div>
+
+<p>For more information about measurements and positioning of system UI elements, see
+<a href="#SpecsAssets">Specifications and Assets</a>.</p>
+
+
+
+<h2 id="DataIntegration">Design Data-Integrated Watch Faces</h2>
+
+<p>Your watch face can show users contextually relevant data and react to it by changing styles
+and colors in your design.</p>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>What do you want your user to know?</h3>
+<p>The first step in designing a data-integrated watch face is to define a conceptual user
+outcome based on available data. First, generate a strong concept or outcome you believe is
+supported by real user needs. What do you want your users to know after they have glanced
+at your design? Once you have identified your outcome, you need to determine how to obtain
+the required data.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Render_Saturn.png" width="200"
+       height="" alt="" style="margin-top:-10px;margin-left:13px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>A watch dial is a timeline; add data to it</h3>
+<p>Your watch face concept may include use of data beyond time, such as weather, calendar
+and fitness data. Consider the inclusion of data integration creatively. Avoid simply
+overlaying a time-based watch face with extra data. Rather, think about how the data can
+be expressed through the lens of time. For example, instead of designing a weather-related
+watch face as a clock with an indication of the current temperature in degrees overlayed,
+you might design a watch face that describes how the temperature will change over the
+course of the day.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Render_Episode.png" width="200"
+       height="" alt="" style="margin-top:-10px;margin-left:13px">
+</div>
+</div>
+
+<div class="layout-content-row" style="margin-top:20px">
+<div class="layout-content-col span-9">
+  <h3>Stick to one message</h3>
+<p>Once you have solidified your conceptual direction or desired outcome, you will need to
+begin visualizing your watch face. The strongest watch face designs are highly glanceable
+and deliver a singular expression of data. In order to identify your singular message, you
+must identify the most important supporting data point. For instance, instead of displaying
+an entire month of calendar events,  you might decide to display only the next
+upcoming event. By a process of reduction, you should arrive at a powerful singular
+expression of data to include in your design.</p>
+</div>
+<div class="layout-content-col span-4">
+  <img src="{@docRoot}design/media/wear/Render_Albumem.png" width="200"
+       height="" alt="" style="margin-top:-10px;margin-left:13px">
+</div>
+</div>
+
+<h3>Begin with some insight and test as you go</h3>
+<p>Make sure your approach begins with insight into the needs and expectations of your users.
+Test your designs with users to check any assumptions you might have made about your design along
+the way. Try making a rough sketch on paper and asking a friend to tell you what it means.
+Try your concept out with lots of different types of data and scenarios. Test your designs
+with an actual watch screen before you start coding.</p>
+
+
+
+<h2 id="CompanionApp">Support the Android Wear Companion App</h2>
+
+<p>The Android Wear companion app gives the user access to all installed watch faces and their
+settings.</p>
+
+<div style="margin:0 auto;width:600px">
+<img src="{@docRoot}design/media/wear/CompanionApp_Build.png" width="350"
+       height="" alt="" style="">
+<img src="{@docRoot}design/media/wear/DeviceSettings_Build.png" width="200"
+       height="" alt="" style="">
+</div>
+
+<h3>Don't use a launcher icon</h3>
+<p>All available watch faces are accessible from the Android Wear companion app or from your
+bundled third party app. There is no need for a stand-alone launcher icon for Android Wear
+watch faces.</p>
+
+<h3>Settings</h3>
+<p>Each watch face that has useful settings can have a Settings panel, accessible from the
+watch itself and from the companion app on the phone. Standard UI components work in most cases,
+but you can explore other creative executions once you have built a foundation designing watch
+faces.</p>
+<p>Settings on the watch should be limited to binary selections or scrollable lists. Settings
+on the phone may include any complex configuration items in addition to the settings
+available on the watch.</p>
+
+
+
+<h2 id="SpecsAssets">Specifications and Assets</h2>
+
+<p>To obtain watch face design examples and detailed measurements for the system UI elements, see
+the <a href="{@docRoot}design/downloads/index.html#Wear">Design Downloads for Android Wear</a>.</p>
diff --git a/docs/html/distribute/engage/engage_toc.cs b/docs/html/distribute/engage/engage_toc.cs
index 596051a..eb176f9 100644
--- a/docs/html/distribute/engage/engage_toc.cs
+++ b/docs/html/distribute/engage/engage_toc.cs
@@ -1,61 +1,61 @@
 <ul id="nav">
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/widgets.html">
         <span class="en">Build Useful Widgets</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/notifications.html">
         <span class="en">Use Rich Notifications</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/gcm.html">
         <span class="en">Integrate GCM</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/easy-signin.html">
         <span class="en">Make Signing In Easy</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/deep-linking.html">
         <span class="en">Deep Link to Bring Users Back</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/game-services.html">
         <span class="en">Encourage Competition</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/analytics.html">
         <span class="en">Understand User Behavior</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/app-updates.html">
         <span class="en">Update Regularly</span></a>
     </div>
   </li>
 
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/community.html">
         <span class="en">Engage Your Community</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
         var:toroot?>distribute/engage/video.html">
         <span class="en">Delight with Videos</span></a>
     </div>
diff --git a/docs/html/distribute/essentials/essentials_toc.cs b/docs/html/distribute/essentials/essentials_toc.cs
index 0369d4d..fe3fc87 100644
--- a/docs/html/distribute/essentials/essentials_toc.cs
+++ b/docs/html/distribute/essentials/essentials_toc.cs
@@ -1,47 +1,47 @@
 <ul id="nav">
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/core.html" zh-cn-lang="应用的核心质量">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/core.html" zh-cn-lang="应用的核心质量">
             <span class="en">Core App Quality</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/tablets.html" zh-cn-lang="平板电脑应用的质量">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/tablets.html" zh-cn-lang="平板电脑应用的质量">
             <span class="en">Tablet App Quality</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/tv.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/tv.html">
             <span class="en">TV App Quality</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/wear.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/wear.html">
             <span class="en">Wear App Quality</span>
           </a>
     </div>
   </li>
     <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/auto.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/auto.html">
             <span class="en">Auto App Quality</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/optimizing-your-app.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/optimizing-your-app.html">
           <span class="en">Optimize Your App</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/best-practices/apps.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/best-practices/apps.html">
           <span class="en">App Best Practices</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/best-practices/games.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/best-practices/games.html">
           <span class="en">Game Best Practices</span>
         </a>
     </div>
diff --git a/docs/html/distribute/essentials/quality/wear.jd b/docs/html/distribute/essentials/quality/wear.jd
index d3689dd..fc1c73f 100644
--- a/docs/html/distribute/essentials/quality/wear.jd
+++ b/docs/html/distribute/essentials/quality/wear.jd
@@ -50,9 +50,8 @@
 </p>
 
 <p class="note">
- <strong>Note:</strong> You will soon be able to submit your apps for Android Wear review.
- Stay tuned for more information about how to submit your apps for Android Wear review through
- the <a href="https://play.google.com/apps/publish/signup/">Google Play Developer Console</a>.
+ <strong>Note:</strong> For information about how to publish your Wear apps in Google Play, see <a
+ href="{@docRoot}distribute/googleplay/wear.html">Distributing to Android Wear</a>.
 </p>
 
 <div class="headerLine">
@@ -83,7 +82,7 @@
 </tr>
 
 <tr>
-  <td rowspan="1" id="general">
+  <td rowspan="3" id="general">
    General
   </td>
 
@@ -100,6 +99,28 @@
 </tr>
 
 <tr>
+ <td id="WR-VF">
+    WR-VF
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      App has Wear functionality that is visible to the user.
+    </p>
+  </td>
+</tr>
+
+<tr>
+ <td id="WR-BF">
+    WR-BF
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      Wear functionality works as expected or as described in the app's Google Play Store listing.
+    </p>
+  </td>
+</tr>
+
+<tr>
   <td rowspan="1" id="packaging">
    Packaging
   </td>
@@ -109,13 +130,13 @@
   </td>
   <td>
     <p style="margin-bottom:.5em;">
-      Wearable apps that run directly on the device are packaged inside the primary handheld app.
+      Wearable apps that are dependent on a handheld app for functionality are packaged inside that
+      handheld app.
       (<a href="{@docRoot}training/wearables/apps/packaging.html">Learn how</a>)
     </p>
   </td>
 </tr>
 
-
 <tr>
   <td rowspan="3" id="functional-notifications">
     Notifications
@@ -187,6 +208,22 @@
   </td>
 </tr>
 
+<tr>
+  <td rowspan="1" id="watchface">
+    Watch Face
+  </td>
+
+  <td id="WR-WF">
+    WR-WF
+  </td>
+  <td>
+    <p style="margin-bottom:.5em;">
+      Apps that include watch faces use the official Watch Face API.
+      (<a href="{@docRoot}training/wearables/watch-faces/index.html">Learn how</a>)
+    </p>
+  </td>
+</tr>
+
 </table>
 
 
@@ -248,8 +285,9 @@
   </td>
   <td>
     <p style="margin-bottom:.5em;">
-      App user interface is formatted appropriately for round displays. App content fits within
-      the physical display area and no text or controls are cut off by the screen edges.
+      App user interface is formatted appropriately for round displays including devices with an
+      inset (or "chin") at the bottom of the screen. App content fits within the physical display
+      area and no text or controls are cut off by the screen edges.
       <br/>
       (<a href="{@docRoot}training/wearables/ui/layouts.html">Learn how</a>)
     </p>
@@ -367,6 +405,7 @@
   </td>
 </tr>
 
+
 </table>
 
 
@@ -399,9 +438,8 @@
   for Wear <a href="#ux">design and interaction</a>.
 </p>
 <p class="note">
- <strong>Note:</strong> You will be able to submit your apps for Android Wear review soon.
- Stay tuned for more information about how to submit your apps for Android Wear review through
- the <a href="https://play.google.com/apps/publish/signup/">Google Play Developer Console</a>.
+ <strong>Note:</strong> For information about how to publish your Wear apps in Google Play, see <a
+ href="{@docRoot}distribute/googleplay/wear.html">Distributing to Android Wear</a>.
 </p>
 
 
diff --git a/docs/html/distribute/googleplay/googleplay_toc.cs b/docs/html/distribute/googleplay/googleplay_toc.cs
index b3aa9bf..3f4dbac 100644
--- a/docs/html/distribute/googleplay/googleplay_toc.cs
+++ b/docs/html/distribute/googleplay/googleplay_toc.cs
@@ -1,35 +1,41 @@
 <ul id="nav">
 
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/about.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/about.html">
             <span class="en">The Google Play Opportunity</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/start.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/start.html">
             <span class="en">Get Started with Publishing</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/developer-console.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/developer-console.html">
           <span class="en">Developer Console</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/guide.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/guide.html">
           <span class="en">Finding Success on Google Play</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/tv.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/tv.html">
           <span class="en">Distributing to <span style="white-space:nowrap">Android TV</span></span>
         </a>
     </div>
   </li>
   <li class="nav-section">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/wear.html">
+          <span class="en">Distributing to <span style="white-space:nowrap">Android Wear</span></span>
+        </a>
+    </div>
+  </li>
+  <li class="nav-section">
     <div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/edu/about.html">
           <span class="en">Google Play for Education</span>
         </a>
diff --git a/docs/html/distribute/googleplay/wear.jd b/docs/html/distribute/googleplay/wear.jd
new file mode 100644
index 0000000..c0a0017
--- /dev/null
+++ b/docs/html/distribute/googleplay/wear.jd
@@ -0,0 +1,275 @@
+page.title=Distributing to Android Wear
+page.image=/design/media/wear/ContextualExample.008_2x.png
+meta.tags="wear", "publish", "quality"
+page.tags="wear", "publish", "googleplay"
+page.metaDescription=Distribute your apps, games, and content to Android Wear.
+
+@jd:body
+
+<div id="qv-wrapper"><div id="qv">
+<h2>How to Participate</h2>
+<ol>
+<li><a href="#understand_guidelines">Understand the guidelines</a></li>
+<li><a href="#develop_app">Develop a great app for Wear</a></li>
+<li><a href="#test_app">Test for Wear App Quality</a></li>
+<li><a href="#opt_in">Opt-in</a></li>
+<li><a href="#track_review">Track your review</a></li>
+</ol>
+
+<h2>You Should Also Read</h2>
+<ol>
+<li><a href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a></li>
+<li><a href="{@docRoot}distribute/essentials/quality/core.html">Core App Quality</a></li>
+</ol>
+
+</div></div>
+
+<p>
+  If you've got a great app, Android Wear and Google Play can help you bring it to users. While all
+  apps are able to send basic notifications to Android Wear devices, you can go much further.
+  Extend your apps to support custom Wear interactions and offer a refined, engaging user
+  experience across all Wear devices. If your apps meet core app quality guidelines on handsets and
+  provide a high-quality experience for Android Wear devices, Google Play will showcase your apps
+  for easy discovery.
+</p>
+
+<p>
+  To get started, review the sections in this document to learn how to distribute your Wear apps
+  to users through Google Play. Be sure to read <a
+  href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> for information on
+  the usability and quality standards that your apps should meet. When your app is ready, you can
+  opt-in for designation as an Android Wear app from the Developer Console.
+</p>
+
+<h2 id="how_to_participate">
+  How to Participate
+</h2>
+
+<p>
+  Google Play lets you make your Wear apps more discoverable for Wear users. You can develop and
+  publish using your existing Developer Console account and your current distribution and pricing
+  settings. It's easy to participate — the sections below outline the process.
+</p>
+
+<h3 id="understand_guidelines">
+  1. Understand guidelines and requirements
+</h3>
+
+<div style="float:right;margin:1em 0 1.5em 2em;">
+  <img src="{@docRoot}images/gp-wear-process.png">
+</div>
+
+<p>
+  To prepare for a successful launch on Android Wear, start by reviewing the guidelines for
+  creating great app experiences on Wear. See the <a href="{@docRoot}design/wear/index.html">Android
+  Wear design guidelines</a> for ideas on extending your app for Wear and details on design and
+  usability.
+</p>
+
+<p>
+  As you get started designing your Wear experience, make sure to read and understand the quality
+  criteria for Wear apps. Only apps that are usable on Wear will be designated as Wear apps on
+  Google Play — your apps can participate if they meet a set of basic quality criteria. See <a
+  href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> for details.
+</p>
+
+<h3 id="develop_app">2. Develop a great app for Wear</h3>
+
+<p>
+Once you have read the guidelines, the next step is to develop your app. The following sections
+describe how to start building a great app experience for Wear.
+</p>
+
+<h4>Design first</h4>
+
+<p>
+  Android Wear aims to provide users with just the right information at just the right time. Great
+  Android Wear experiences are launched automatically, glanceable, and
+  require zero or low user interaction. Although all apps can send basic notifications to Wear
+  devices without any modification, great apps built for Wear are refined to offer a polished and
+  high-quality experience, work on different screen layouts, and deliver a compelling feature set
+  for users.
+</p>
+
+<p>
+  As you consider your Wear app, review the <a href=
+  "{@docRoot}training/building-wearables.html">developer documentation</a> and <a
+  href="{@docRoot}design/wear/index.html">usability guidelines</a> and plan on utilizing them to the
+  greatest extent possible. You can design a great notification experience for users with the APIs
+  provided in the SDK and support library. You may also choose to build an app that runs directly
+  on the wearable.
+</p>
+
+<h4>Package your app</h4>
+
+<p>
+  We recommend that you deliver your Wear experience as part of your existing app for phones,
+  tablets, and other devices, using the same package name and store listing. This lets users
+  upgrade to your Wear experience seamlessly and also lets you take advantage of the reviews and
+  ratings you’ve earned in your app for phones and tablets. For wearable apps that depend on an
+  app for functionality, you should always package it within that app. To learn how, read <a
+  href="{@docRoot}training/wearables/apps/packaging.html">Packaging Wearable Apps</a>.
+</p>
+
+<h4>Test on a variety of devices</h4>
+
+<p>
+  Throughout design and development, it's important to have suitable devices on which to prototype
+  and test your user experience. It's highly recommended that you acquire one or more Android Wear
+  devices or develop with different emulator configurations and set up your testing environment as
+  early as possible. It’s important that you optimize your design on both square and round layouts.
+</p>
+
+<h3 id="test_app">3. Test for Wear App Quality</h3>
+
+<p>
+  Your Wear apps should be designed to perform well and look great on Android Wear, and they should
+  offer the best user experience possible. Google Play will showcase selected high-quality Wear
+  apps for easy discovery. Here’s how you can participate and deliver an Android Wear app that
+  users will enjoy:
+</p>
+
+<ul>
+  <li>Meet Core App Quality guidelines
+    <ul>
+      <li>Follow <a href="{@docRoot}design/index.html">Android Design
+      guidelines</a>. Pay special attention to using <a href=
+      "http://www.google.com/design/spec/material-design/introduction.html">material
+      design</a> in your app.
+      </li>
+
+      <li>Test your apps against the <a href=
+      "{@docRoot}distribute/essentials/quality/core.html">Core App Quality
+      guidelines</a>.
+      </li>
+    </ul>
+  </li>
+  <li>Meet <a href="{@docRoot}distribute/essentials/quality/wear.html">Wear App
+  Quality</a> criteria
+    <ul>
+      <li>Follow our best practices for <a href="{@docRoot}training/building-wearables.html">
+      Wear app development</a></li>
+      <li>Make sure your app meets all of the <a href=
+      "{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> criteria</li>
+    </ul>
+  </li>
+</ul>
+
+<h3 id="opt_in">4. Opt-in to Android Wear and publish</h3>
+
+<p>
+  When you've built your release-ready APK and tested to ensure that it meets all of the <a
+  href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> criteria, upload it
+  to the Developer Console. Update your store listing with Wear screenshots and set distribution
+  options as needed. If you aren't familiar with how to prepare for launch on Google Play, see the
+  <a href="{@docRoot}distribute/googleplay/publish/preparing.html">Launch Checklist.</a>
+</p>
+
+<p>
+  Before you publish to users, you may opt-in to Android Wear from the <strong>Pricing and
+  Distribution</strong> section of the Developer Console. Opt-in means that you want your app to
+  be made more discoverable to Android Wear users through Google Play, and that your app meets <a
+  href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> criteria.
+</p>
+
+<p>
+  After you've opted-in and saved changes, you can publish your app as usual. In addition, Google
+  Play submits your app for review against the <a
+  href="{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> criteria and
+  notifies you of the result. See the next section for details on how to track the approval status
+  of your app.
+</p>
+
+<p>
+  If your app meets all <a href="{@docRoot}distribute/essentials/quality/wear.html">Wear App
+  Quality</a> criteria, Google Play makes it more discoverable to Android Wear users. Your app is
+  also eligible for higher-visibility featuring in app collections and promotions.
+</p>
+
+<p>
+  Note that opt-in and review do not affect the availability of your app in the Google Play Store
+  &mdash; your app is available as soon as you publish.
+</p>
+
+<p>
+  Here are the steps to opt-in to Android Wear in the Developer Console:
+</p>
+
+<ol>
+  <li>Make sure your app meets all <a href=
+  "{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> criteria
+  </li>
+
+  <li>Add Wear screenshots to the app’s store listing
+  </li>
+
+  <li>In the <strong>All Applications</strong> page, click the app you want to opt-in.
+  </li>
+
+  <li>Under <strong>Pricing and Distribution</strong>, scroll down to find <em>Android Wear</em>
+  and the opt-in checkbox.
+  </li>
+
+  <li>Click the checkbox next to <em>Distribute your app on Android Wear</em>.
+  </li>
+
+  <li>Click <strong>Save</strong> to save your Pricing and Distribution changes.
+  </li>
+</ol>
+
+<div style="padding-top:1em">
+  <img style="border:2px solid #ddd;" src="{@docRoot}images/gp-wear-opt-in.png">
+  <p class="caption">
+    <strong>Opt-in for Wear:</strong> Include your app in Android Wear by opting-in from the
+    Developer Console.
+  </p>
+</div>
+
+<h3 id="track_review">5. Track your review and approval</h3>
+
+<p>
+  If your app meets the technical and quality criteria for Android Wear, as described above, your
+  app will be made more discoverable for users on Android Wear. If your app doesn’t meet the
+  criteria, you’ll receive a <strong>notification email sent to your developer account
+  address</strong>, with a summary of the areas that you need to address. When you’ve made the
+  necessary adjustments, you can upload a new version of your app to the Developer Console.
+</p>
+
+<p>
+  At any time, you can check the review and approval status of your app in the Developer Console,
+  under <em>Android Wear</em> in the app's <strong>Pricing and Distribution</strong>
+  page.
+</p>
+
+<p>
+  There are three approval states:
+</p>
+
+<ul>
+  <li>
+    <em>Pending</em> — Your app was sent for review and the review is not yet complete.
+  </li>
+
+  <li>
+    <em>Approved</em> — Your app was reviewed and approved. The app will be made more discoverable
+    to Android Wear users.
+  </li>
+
+  <li>
+    <em>Not approved</em> — Your app was reviewed and not approved. Check the notification email
+    for information about why the app was not approved. You can address any issues and opt-in and
+    publish again to initiate another review.
+  </li>
+</ul>
+
+<p>To understand how your apps are evaluated, please see the <a href=
+"{@docRoot}distribute/essentials/quality/wear.html">Wear App Quality</a> document. </p>
+
+
+  <h3>Related resources</h3>
+
+  <div class="resource-widget resource-flow-layout col-13"
+    data-query="collection:wearlanding"
+    data-cardSizes="6x2"
+    data-maxResults="3">
+  </div>
diff --git a/docs/html/distribute/monetize/monetize_toc.cs b/docs/html/distribute/monetize/monetize_toc.cs
index aeb6cf8..8211689 100644
--- a/docs/html/distribute/monetize/monetize_toc.cs
+++ b/docs/html/distribute/monetize/monetize_toc.cs
@@ -1,35 +1,35 @@
 <ul id="nav">
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/premium.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/premium.html">
             <span class="en">Premium</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/freemium.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/freemium.html">
             <span class="en">Freemium</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/subscriptions.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/subscriptions.html">
           <span class="en">Subscriptions</span>
         </a
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/ecommerce.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/ecommerce.html">
           <span class="en">E-commerce</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/ads.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/ads.html">
           <span class="en">Ads</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/payments.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/payments.html">
           <span class="en">Purchasing</span>
         </a>
     </div>
diff --git a/docs/html/distribute/stories/stories_toc.cs b/docs/html/distribute/stories/stories_toc.cs
index 944dabe..54b7639 100644
--- a/docs/html/distribute/stories/stories_toc.cs
+++ b/docs/html/distribute/stories/stories_toc.cs
@@ -1,22 +1,22 @@
 <ul id="nav">
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/index.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/index.html">
             <span class="en">Videos</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/localization.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/localization.html">
             <span class="en">Going Global</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/games.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/games.html">
             <span class="en">Games</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/tablets.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/stories/tablets.html">
           <span class="en">Tablets</span>
         </a>
     </div>
diff --git a/docs/html/distribute/users/users_toc.cs b/docs/html/distribute/users/users_toc.cs
index 1f173cb..edfa874 100644
--- a/docs/html/distribute/users/users_toc.cs
+++ b/docs/html/distribute/users/users_toc.cs
@@ -1,35 +1,35 @@
 <ul id="nav">
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/know-your-user.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/know-your-user.html">
             <span class="en">Know Your User</span></a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/your-listing.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/your-listing.html">
             <span class="en">Create a Great Listing</span>
           </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-buzz.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-buzz.html">
           <span class="en">Build Buzz</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-community.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-community.html">
           <span class="en">Build Community</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/expand-to-new-markets.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/expand-to-new-markets.html">
           <span class="en">Expand to New Markets</span>
         </a>
     </div>
   </li>
   <li class="nav-section">
-    <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/promote-with-ads.html">
+    <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/promote-with-ads.html">
           <span class="en">Promote with Ads</span>
         </a>
     </div>
diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd
index 8578f96..b3cd4cf 100644
--- a/docs/html/google/play-services/index.jd
+++ b/docs/html/google/play-services/index.jd
@@ -134,6 +134,22 @@
     when compiling your app. For more details, see the Android Studio setup
     instructions in
     <a href="{@docRoot}google/play-services/setup.html">Setting Up Google Play Services</a>.
+  </li>
+  <li><strong>Deprecated clients</strong> - The {@code ActivityRecognitionClient},
+    {@code LocationClient}, and {@code PlusClient} classes are deprecated. If
+    you used those APIs in your app and want to call Google Play services 6.5
+    or higher APIs, you must switch to the new programming model that utilizes
+    <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>. For more information about using <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>, see <a href="{@docRoot}google/auth/api-client.html">Accessing Google APIs</a>.
+    <p>Use these APIs instead of the deprecated APIs:</p>
+    <ul>
+      <li>If you were previously using {@code ActivityRecognitionClient}, call
+        <a href="{@docRoot}reference/com/google/android/gms/location/ActivityRecognition.html">{@code ActivityRecognition}</a> instead.</li>
+      <li>If you were previously using {@code LocationClient}, call the APIs in the
+        <a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">{@code com.google.android.gms.location} package</a> instead.</li>
+      <li>If you were previously using {@code PlusClient}, call the APIs in the
+        <a href="{@docRoot}reference/com/google/android/gms/plus/package-summary.html">{@code com.google.android.gms.plus} package</a> instead.</li>
+    </ul>
+  </li>
 </ul>
 </dd>
 </dl>
diff --git a/docs/html/images/gp-wear-opt-in.png b/docs/html/images/gp-wear-opt-in.png
new file mode 100644
index 0000000..139ce50
--- /dev/null
+++ b/docs/html/images/gp-wear-opt-in.png
Binary files differ
diff --git a/docs/html/images/gp-wear-process.png b/docs/html/images/gp-wear-process.png
new file mode 100644
index 0000000..4b55aed
--- /dev/null
+++ b/docs/html/images/gp-wear-process.png
Binary files differ
diff --git a/docs/html/images/tools/projectview01.png b/docs/html/images/tools/projectview01.png
index 90589fb..2deb752 100644
--- a/docs/html/images/tools/projectview01.png
+++ b/docs/html/images/tools/projectview01.png
Binary files differ
diff --git a/docs/html/images/tools/studio-cloudmodule.png b/docs/html/images/tools/studio-cloudmodule.png
index b7c4fb7..cffa2d5 100644
--- a/docs/html/images/tools/studio-cloudmodule.png
+++ b/docs/html/images/tools/studio-cloudmodule.png
Binary files differ
diff --git a/docs/html/images/tools/studio-helloworld-design.png b/docs/html/images/tools/studio-helloworld-design.png
index ff90c6b..a355e7a 100644
--- a/docs/html/images/tools/studio-helloworld-design.png
+++ b/docs/html/images/tools/studio-helloworld-design.png
Binary files differ
diff --git a/docs/html/images/tools/studio-helloworld-text.png b/docs/html/images/tools/studio-helloworld-text.png
index 5dde675..28e39fe 100644
--- a/docs/html/images/tools/studio-helloworld-text.png
+++ b/docs/html/images/tools/studio-helloworld-text.png
Binary files differ
diff --git a/docs/html/images/tools/studio-projectview_scripts.png b/docs/html/images/tools/studio-projectview_scripts.png
index 3e7b9cd..a0565c5 100644
--- a/docs/html/images/tools/studio-projectview_scripts.png
+++ b/docs/html/images/tools/studio-projectview_scripts.png
Binary files differ
diff --git a/docs/html/images/tools/studio-samples-githubaccess.png b/docs/html/images/tools/studio-samples-githubaccess.png
index 991bf69..3980361 100644
--- a/docs/html/images/tools/studio-samples-githubaccess.png
+++ b/docs/html/images/tools/studio-samples-githubaccess.png
Binary files differ
diff --git a/docs/html/images/tools/studio-setup-wizard.png b/docs/html/images/tools/studio-setup-wizard.png
index f84660a4..ccd92d3 100644
--- a/docs/html/images/tools/studio-setup-wizard.png
+++ b/docs/html/images/tools/studio-setup-wizard.png
Binary files differ
diff --git a/docs/html/images/tools/studio-tvwearsupport.png b/docs/html/images/tools/studio-tvwearsupport.png
index 02bf484..88343a6 100644
--- a/docs/html/images/tools/studio-tvwearsupport.png
+++ b/docs/html/images/tools/studio-tvwearsupport.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index f483e31..ab5a655 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -4,7 +4,7 @@
     "resources": [
       "training/building-wearables.html",
       "training/material/index.html",
-      "sdk/installing/studio.html"
+      "sdk/index.html"
     ]
   },
   "index/primary/zhcn": {
@@ -67,6 +67,7 @@
     "resources": [
       "distribute/googleplay/guide.html",
       "distribute/googleplay/tv.html",
+      "distribute/googleplay/wear.html",
       "distribute/googleplay/edu/about.html"
     ]
   },
@@ -996,6 +997,14 @@
       "training/tv/index.html"
     ]
   },
+  "wearlanding": {
+    "title": "",
+    "resources": [
+      "design/wear/index.html",
+      "training/building-wearables.html",
+      "training/wearables/ui/index.html"
+    ]
+  },
   "play_dev_guide": {
     "title": "",
     "resources": [
diff --git a/docs/html/sdk/exploring.jd b/docs/html/sdk/exploring.jd
deleted file mode 100644
index b34c1cf..0000000
--- a/docs/html/sdk/exploring.jd
+++ /dev/null
@@ -1,10 +0,0 @@
-page.title=Exploring the SDK
-excludeFromSuggestions=true
-walkthru=1
-
-@jd:body
-
-
-
-
-
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 7b40f00..3324c2d 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,48 +1,49 @@
-page.title=Android Studio
-page.tags=download
+page.title=Download Android Studio and SDK Tools
+page.tags=sdk, android studio
 page.template=sdk
 header.hide=1
-page.metaDescription=Download the official Android developer tools to build apps for Android phones, tablets, wearables, TVs, and more.
+page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more.
 
-studio.version=1.0.0
+studio.version=1.0.1
 
-studio.linux_bundle_download=android-studio-ide-135.1629389-linux.zip
-studio.linux_bundle_bytes=243909934
-studio.linux_bundle_checksum=601a302f10cf8a22ba4216e0884a035bdfec38b3
+studio.linux_bundle_download=android-studio-ide-135.1641136-linux.zip
+studio.linux_bundle_bytes=243917559
+studio.linux_bundle_checksum=7c8f2d0cec21b98984cdba45ab5a25f26d67f23a
 
-studio.mac_bundle_download=android-studio-ide-135.1629389.dmg
-studio.mac_bundle_bytes=245757810
-studio.mac_bundle_checksum=0d9e0e230ece9f2e696b1b076c36ee1e73edcf3c
+studio.mac_bundle_download=android-studio-ide-1641136.dmg
+studio.mac_bundle_bytes=245729073
+studio.mac_bundle_checksum=49506ba2cf6b56be4f7d07e6a00c4ec3ba2249d5
 
-studio.win_bundle_exe_download=android-studio-bundle-135.1629389.exe
-studio.win_bundle_exe_bytes=852499624
-studio.win_bundle_exe_checksum=0c8a3b45385a698b43a47757fdd6a83ca837abd2
+studio.win_bundle_exe_download=android-studio-bundle-135.1641136.exe
+studio.win_bundle_exe_bytes=868344232
+studio.win_bundle_exe_checksum=1931dbaeadb52f5e0a8ba6e2ae60d9df20b2076b
 
-studio.win_notools_exe_download=android-studio-ide-135.1629389.exe
-studio.win_notools_exe_bytes=262099808
-studio.win_notools_exe_checksum=bfc6e9397f72969bcb3db80c9abe3a205540c8ab
+studio.win_notools_exe_download=android-studio-ide-135.1641136.exe
+studio.win_notools_exe_bytes=260272840
+studio.win_notools_exe_checksum=464d1c5497ab3d1bdef441365791ab36c89cd5ae
 
-studio.win_bundle_download=android-studio-ide-135.1629389-windows.zip
-studio.win_bundle_bytes=246241434
-studio.win_bundle_checksum=6951e678a41b94b6172276727537db8590be7270
+studio.win_bundle_download=android-studio-ide-135.1641136-windows.zip
+studio.win_bundle_bytes=246249059
+studio.win_bundle_checksum=6d6856aca83f6ff747ca40b10f70edfbbcccd91c
 
 
 
-sdk.linux_download=android-sdk_r24-linux.tgz
-sdk.linux_bytes=141308131
-sdk.linux_checksum=3cc1fcec302a8478e240e42b94dd2de73b9d0cc9
 
-sdk.mac_download=android-sdk_r24-macosx.zip
-sdk.mac_bytes=88535806
-sdk.mac_checksum=89b256c82e6ab432881fa7d726bdd0541c656616
+sdk.linux_download=android-sdk_r24.0.1-linux.tgz
+sdk.linux_bytes=141304203
+sdk.linux_checksum=fb46b9afa04e09d3c33fa9bfee5c99e9ec6a9523
 
-sdk.win_download=android-sdk_r24-windows.zip
-sdk.win_bytes=140738187
-sdk.win_checksum=8d20f800cbace1b92873ebba1e16ff134a2b062b
+sdk.mac_download=android-sdk_r24.0.1-macosx.zip
+sdk.mac_bytes=88535741
+sdk.mac_checksum=7097c09c72645d7ad33c81a37b1a1363a9df2a54
 
-sdk.win_installer=installer_r24-windows.exe
-sdk.win_installer_bytes=92179689
-sdk.win_installer_checksum=71ec3d91a4239b44128bf43add888bc357776be9
+sdk.win_download=android-sdk_r24.0.1-windows.zip
+sdk.win_bytes=140743633
+sdk.win_checksum=cc49974e8bfcc865ffe0d887e9a74cf52085c632
+
+sdk.win_installer=installer_r24.0.1-windows.exe
+sdk.win_installer_bytes=92180986
+sdk.win_installer_checksum=505d7a95647bccc194b7aa707854422d9c7288d5
 
 
 
@@ -429,8 +430,9 @@
 </div>
 
 
-<p>If you've been using Eclipse with ADT, be aware that the ADT plugin is no longer in active
-development, so you should migrate to Android Studio as soon as possible. For help moving projects,
+<p>If you have been using Eclipse with ADT, be aware that Android Studio is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
 see <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android
 Studio</a>.</p>
 
diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd
index 744ce15..9a02382 100644
--- a/docs/html/sdk/installing/index.jd
+++ b/docs/html/sdk/installing/index.jd
@@ -1,4 +1,5 @@
 page.title=Installing the Android SDK
+excludeFromSuggestions=true
 
 page.tags=sdk tools
 helpoutsWidget=true
@@ -28,9 +29,8 @@
 <!-- ################    STUDIO    ##################### -->
 <div id="studio" heading="Installing Android Studio" style="display:none">
 
-<p>Android Studio provides the tools you need to start developing apps, including
-the Android Studio IDE (powered by IntelliJ) and guides you to install
-the Android SDK tools to streamline your Android app development.</p>
+<p>Android Studio provides everything you need to start developing apps for Android, including
+the Android Studio IDE and the Android SDK tools.</p>
 
 <p>If you didn't download Android Studio, go <a href="{@docRoot}sdk/index.html"
 ><b>download Android Studio now</b></a>, or switch to the
@@ -39,7 +39,8 @@
 
 
 <p>Before you set up Android Studio, be sure you have installed
-JDK 6 or greater (the JRE alone is not sufficient). To check if you
+JDK 6 or higher (the JRE alone is not sufficient)&mdash;JDK 7 is required when
+developing for Android 5.0 and higher. To check if you
 have JDK installed (and which version), open a terminal and type <code>javac -version</code>.
 If the JDK is not available or the version is lower than 6,
 <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" class="external-link"
@@ -57,7 +58,7 @@
 <p><b>To set up Android Studio on Windows:</b></p>
   <ol>
     <li>Launch the <code>.exe</code> file you just downloaded.</li>
-    <li>Follow the setup wizard to install Android Studio and the SDK Tools.
+    <li>Follow the setup wizard to install Android Studio and any necessary SDK tools.
 
     <p>On some Windows systems, the launcher script does not find where Java is installed.
       If you encounter this problem,
@@ -88,7 +89,7 @@
   <ol>
     <li>Launch the {@code .dmg} file you just downloaded.</li>
     <li>Drag and drop Android Studio into the Applications folder.
-    <li>Open Android Studio and follow the instructions to set up the SDK.
+    <li>Open Android Studio and follow the setup wizard to install any necessary SDK tools.
       <p>
       Depending on your security settings, when you attempt to open Android Studio, you might
       see a warning that says the package is damaged and should be moved to the trash. If this
@@ -118,7 +119,7 @@
       <p>You may want to add {@code android-studio/bin/} to your PATH environmental
       variable so that you can start Android Studio from any directory.</p>
     </li>
-    <li>Follow the links to install the SDK tools outside of the Android Studio directories.</li>
+    <li>Follow the setup wizard to install any necessary SDK tools.</li>
   </ol>
 
 </div><!-- end linux -->
@@ -226,8 +227,7 @@
       <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/JavaInstallation</a></li>
     </ul>
   </li>
-  <li>Here are the steps to install Java and Eclipse, prior to installing
-  the Android SDK and ADT Plugin.
+  <li>Here are the steps to install Java:
     <ol>
       <li><p>If you are running a 64-bit distribution on your development
       machine, you need to install additional packages first. For Ubuntu 13.10 (Saucy Salamander)
@@ -241,13 +241,6 @@
       <pre class="no-pretty-print">apt-get install ia32-libs</pre>
       </li>
       <li>Next, install Java: <pre class="no-pretty-print">apt-get install sun-java6-jdk</pre></li>
-      <li>The Ubuntu package manager does not currently offer an Eclipse 3.7
-      version for download, so we recommend that you download Eclipse from
-      eclipse.org (<a
-      href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>).
-      A Java or RCP version of Eclipse is recommended.</li>
-      <li>Follow the steps given in previous sections to install the SDK
-      and the ADT plugin. </li>
     </ol>
   </li>
 </ul>
@@ -272,47 +265,6 @@
 
 
 
-<!-- ###################    ADT BUNDLE     ####################### -->
-<div id="adt" heading="Installing the Eclipse ADT Bundle" style="display:none">
-
-
-<p>The Eclipse ADT Bundle provides everything you need to start developing apps, including
-the Android SDK tools and a version of the Eclipse IDE with built-in ADT
-(Android Developer Tools) to streamline your Android app development.</p>
-
-<p>If you didn't download the Eclipse ADT bundle, go <a href="{@docRoot}tools/eclipse/index.html"
-><b>download the Eclipse ADT bundle now</b></a>, or switch to the
-<a href="{@docRoot}sdk/installing/index.html?pkg=studio">Android Studio
-install</a> or <a href="{@docRoot}sdk/installing/index.html?pkg=tools">stand-alone SDK Tools
-install</a> instructions</i>.</p>
-
-<div class="procedure-box">
-<p><b>To set up the ADT Bundle:</b></p>
-<ol>
-<li>Unpack the ZIP file
-(named {@code adt-bundle-&lt;os_platform>.zip}) and save it to an appropriate location,
-such as a "Development" directory in your home directory.</li>
-<li>Open the {@code adt-bundle-&lt;os_platform>/eclipse/} directory and launch
-<strong>Eclipse</strong>.</li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Do not move any of the files or directories
-from the {@code adt-bundle-&lt;os_platform>} directory. If you move the {@code eclipse/}
-or {@code sdk/} directory, ADT will not be able to locate the SDK and you'll
-need to manually update the ADT preferences.</p>
-</div>
-
-<p>Eclipse with ADT is now ready and loaded with the Android developer tools, but there are still
-a couple packages you should add to make your Android SDK complete.</p>
-
-<p class="paging-links">
-<a href="{@docRoot}sdk/installing/adding-packages.html" class="next-page-link">
-Continue: Adding SDK Packages</a></p>
-
-
-</div>
-<!-- ################    END ADT BUNDLE    ##################### -->
-
 
 
 
@@ -368,10 +320,6 @@
   // Show the SDK Tools (other IDE) instructions
   $("h1").text($("#tools").attr('heading'));
   $("#tools").show();
-} else if (package == "adt") {
-  // Show the ADT instructions
-  $("h1").text($("#adt").attr('heading'));
-  $("#adt").show();
 } else if (package == "studio") {
   // Show the Android Studio instructions
   $("h1").text($("#studio").attr('heading'));
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index c8200aa..0114848 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -15,12 +15,18 @@
 UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.
 </p>
 
-<p class="note"><strong>Note:</strong> You should install the ADT plugin
-only if you already have an Eclipse installation that you want to continue using. If you do not
-have Eclipse installed, you should instead <b><a href="{@docRoot}sdk/index.html">install
-the complete Android SDK</a></b>, which includes the latest IDE for Android developers.</p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-<p>Your existing Eclipse installation must meet these requirements:</p>
+
+<p>You should install the ADT plugin
+only if you already have an Eclipse installation that you want to continue using.
+Your existing Eclipse installation must meet these requirements:</p>
     <ul>
       <li><a href="http://eclipse.org/mobile/">Eclipse</a> 3.7.2 (Indigo) or greater
 <p class="note"><strong>Note:</strong> Eclipse 3.6 (Helios) is no longer
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index 06b9e3f..3c04cb4 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -6,7 +6,8 @@
 <div id="qv">
 <h2>See also</h2>
 <ul>
-  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
+  class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
  >Eclipse Compatibility Mode</a></li>
  <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
@@ -15,25 +16,12 @@
 </div>
 </div>
 
-<p>If you're currently using Eclipse with ADT, we recommend you migrate to
-<a href="{@docRoot}tools/studio/index.html">Android Studio</a> as soon as possible, because
-the ADT plugin for Eclipse is no longer in active development.</p>
 
+<p>If you have been using <a href="{@docRoot}tools/help/adt.html">Eclipse with ADT</a>, be aware
+that <a href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE for
+Android, so you should migrate to Android Studio to receive all the latest IDE updates.</p>
 
-<p>To migrate existing Android projects from Eclipse,
-you should export your projects from Eclipse in order to generate
-Gradle build files:</p>
-
-<ol>
-  <li>In Eclipse, select <strong>File &gt; Export</strong>.</li>
-  <li>Select <strong>Generate Gradle build files</strong> inside the Android folder, then click
-  <strong>Next</strong>.</li>
-  <li>Click <strong>Browse</strong> to find your project to export.</li>
-  <li>Select your project from the list, click <strong>OK</strong>, then <strong>Finish</strong>.</li>
-</ol>
-
-
-<p>You can then import the project into Android Studio:</p>
+<p>To migrate existing Android projects, simply import them using Android Studio:</p>
 
 <ol>
   <li>In Android Studio, close any projects currently open. You should see the
@@ -45,11 +33,10 @@
   <strong>OK</strong>. (You do not need to specify the Gradle home.)</li>
 </ol>
 
-<p>It's possible to import an existing Android project to Android Studio even if you
-don't generate a Gradle build file from Eclipse&mdash;Android Studio will successfully build and
-run projects using an existing Ant build file. However, in order to take advantage of build
-variants and other advanced features in the future,
-you should generate a Gradle build file using
-the ADT plugin or write your own Gradle build file for use with Android Studio.</p>
+<p>Android Studio properly updates the project structure and creates the appropriate
+Gradle build file.</p>
 
-<p><a href="{@docRoot}tools/studio/index.html">Learn more about Android Studio</a>.</p>
+<p>For more help getting started with Android Studio and the IntelliJ user experience,
+<a href="{@docRoot}tools/studio/index.html">learn more about Android Studio</a> and
+read <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
+  class="external-link">FAQ on Migrating to IntelliJ IDEA</a>.</p>
diff --git a/docs/html/sdk/installing/studio-build.jd b/docs/html/sdk/installing/studio-build.jd
index c80368f..4fe9071 100644
--- a/docs/html/sdk/installing/studio-build.jd
+++ b/docs/html/sdk/installing/studio-build.jd
@@ -13,7 +13,7 @@
    <li><a href="{@docRoot}sdk/installing/studio.html">
    Getting Started with Android Studio</a></li>
    <li><a href="{@docRoot}tools/studio/index.html">Android Studio Basics</a></li>
-   <li><a href="{@docRoot}tools/eclipse/migrate-adt.html">Migrating from Eclipse</a></li>
+   <li><a href="{@docRoot}sdk/installing/migrate.html">Migrating from Eclipse</a></li>
 </div>
 </div>
 
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd
index fba7a70..8e7e345 100644
--- a/docs/html/sdk/installing/studio-tips.jd
+++ b/docs/html/sdk/installing/studio-tips.jd
@@ -40,25 +40,19 @@
 add all missing attributs</em>. Clicking the message adds the missing attributes to the layout.</p>
 
 
-<h2>Output window message filtering</h2>
-<p>When checking build results, you can filter messages by <em>message type</em> to quickly
-locate messages of interest.</p>
-<img src="{@docRoot}images/tools/studio-outputwindowmsgfiltering.png" style="width:200px"style="width:200px" />
-<p class="img-caption"><strong>Figure 14.</strong> Filter Build Messages</p>
-
 <h3> Bitmap rendering in the debugger</h3>
 <p>While debugging, you can now right-click on bitmap variables in your app and invoke
 <em>View Bitmap</em>. This fetches the associated data from the debugged process and renders
 the bitmap in the debugger. </p>
 <p><img src="{@docRoot}images/tools/studio-bitmap-rendering.png" style="width:350px"/></p>
-<p class="img-caption"><strong>Figure 2.</strong> Bitmap Rendering</p>
+<p class="img-caption"><strong>Figure 1.</strong> Bitmap Rendering</p>
 
 
 <h3>Output window message filtering</h3>
 <p>When checking build results, you can filter messages by <em>message type</em> to quickly
 locate messages of interest.</p>
 <img src="{@docRoot}images/tools/studio-outputwindowmsgfiltering.png" style="width:200px"style="width:200px" />
-<p class="img-caption"><strong>Figure 3.</strong> Filter Build Messages</p>
+<p class="img-caption"><strong>Figure 2.</strong> Filter Build Messages</p>
 
 
 <h3>Hierarchical parent setting</h3>
@@ -79,7 +73,7 @@
 multiple devices simultaneously, select <strong>Preview All Screen Sizes</strong> from the
 device drop-down.</p>
 <p><img src="{@docRoot}images/tools/studio-previewall.png" style="width:350px"/></p>
-<p class="img-caption"><strong>Figure 4.</strong> Preview All Screens</p>
+<p class="img-caption"><strong>Figure 3.</strong> Preview All Screens</p>
 
 <p>You can switch to the graphical editor by clicking <strong>Design</strong> at the
 bottom of the window. While editing in the Design view, you can show and hide the
@@ -166,7 +160,7 @@
 </strong> <code>F1</code>, see the theme inheritance hierarchy, and resolved values for the
 various attributes.</p>
 <img src="{@docRoot}images/tools/studio-allocationtracker.png" style="width:300px" />
-<p class="img-caption"><strong>Figure 1.</strong> Allocation Tracker</p>
+<p class="img-caption"><strong>Figure 4.</strong> Allocation Tracker</p>
 
 
 <h3 id="key-commands">Keyboard Commands</h3>
diff --git a/docs/html/tools/eclipse/index.jd b/docs/html/tools/eclipse/index.jd
deleted file mode 100644
index c8a998b..0000000
--- a/docs/html/tools/eclipse/index.jd
+++ /dev/null
@@ -1,37 +0,0 @@
-page.title=Eclipse ADT
-@jd:body
-
-
-<div id="qv-wrapper">
-<div id="qv">
-  <h2>See also</h2>
-  <ol>
-    <li><a href="{@docRoot}tools/sdk/index.html">Downloading Android Studio</a></li>
-    <li><a href="{@docRoot}tools/studio/index.html">Android Studio</a></li>
-    <li><a href="{@docRoot}tools/eclipse/migrate-adt.html">Migrating to Android Studio</a></li>
-  </ol>
-</div>
-</div>
-
-
-<p>The Android Developer Tools (ADT) plugin for Eclipse provides a professional-grade development
-environment for building Android apps. It's a full Java IDE with advanced features to help you build,
-test, debug, and package your Android apps. </p>
-
-<p>Android developers are encouraged to <a href="{@docRoot}tools/eclipse/migrate-adt.html">migrate
-to Android Studio</a> as the Eclipse ADT is no longer in active development.
-</p>
-
-<p>The Android Studio build system replaces the Apache Ant build software used with Eclipse ADT
-with an Android plugin for <em>Gradle</em>. <a href="http://www.gradle.org/">Gradle</a> is an
-advanced build toolkit that manages dependencies and allows you to define custom build logic. Android
-Studio also adds support for Maven-based build dependencies, build variants, advanced code
-completion and refactoring. For more details about Android Studio, see the
-<a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.
-
-<p>If you still wish to get started with the ADT plugin,
-<a href="{@docRoot}tools/eclipse/installing-adt.html">download and install the Eclipse ADT plugin.</a>
-</p>
-
-</div>
-</div>
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 1bb3015..8abe1b4 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -24,63 +24,30 @@
         </li>
 
         <li><a href="#refactoring">Layout Factoring Support</a></li>
-        <li><a href="#Updating">Updating the ADT Plugin</h2>
+        <li><a href="#Updating">Updating the ADT Plugin</a></li>
 
       </ol>
-
-      <h2>Related videos</h2>
-
-      <ol>
-        <li><a href="{@docRoot}videos/index.html#v=Oq05KqjXTvs">Android Developer Tools
-            Google I/O Session</a>
-        </li>
-      </ol>
-
-      <h2>See also</h2>
-
-      <ol>
-        <li><a href="http://tools.android.com/recent">Android Tools change blog</a></li>
-      </ol>
     </div>
   </div>
 
   <p>ADT (Android Developer Tools) is a plugin for Eclipse that provides a suite of
   tools that are integrated with the Eclipse IDE. It offers you access to many features that help
-  you develop Android applications quickly. ADT
+  you develop Android applications. ADT
   provides GUI access to many of the command line SDK tools as well as a UI design tool for rapid
   prototyping, designing, and building of your application's user interface.</p>
 
-  <p>Because ADT is a plugin for Eclipse, you get the functionality of a well-established IDE,
-  along with Android-specific features that are bundled with ADT. The following
-  describes important features of Eclipse and ADT:</p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-  <dl>
-    <dt><strong>Integrated Android project creation, building, packaging, installation, and
-    debugging</strong></dt>
+<p>If you still wish to use the ADT plugin for Eclipse, see
+<a href="{@docRoot}sdk/installing/installing-adt.html">Installing Eclipse Plugin.</a>
+</p>
 
-    <dd>ADT integrates many development workflow tasks into Eclipse, making it easy for you to
-    rapidly develop and test your Android applications.</dd>
-
-    <dt><strong>SDK Tools integration</strong></dt>
-
-    <dd>Many of the <a href="#tools">SDK tools</a> are integrated into Eclipse's menus,
-    perspectives, or as a part of background processes ran by ADT.</dd>
-
-    <dt><strong>Java programming language and XML editors</strong></dt>
-
-    <dd>The Java programming language editor contains common IDE features such as compile time
-    syntax checking, auto-completion, and integrated documentation for the Android framework APIs.
-    ADT also provides custom XML editors that let you
-    edit Android-specific XML files in a form-based UI. A graphical layout editor lets you design
-    user interfaces with a drag and drop interface.</dd>
-
-    <dt><strong>Integrated documentation for Android framework APIs</strong></dt>
-    <dd>You can access documentation by hovering over classes, methods, or variables.</dd>
-  </dl>
-
-  <p>You can find the most up-to-date and more detailed information about changes and new features
-on the <a  href="http://tools.android.com/recent">Recent Changes</a> page at the Android  Tools
-Project site.</p>
 
   <h2 id="tools">SDK Tools Integration</h2>
 
@@ -542,10 +509,10 @@
 revision of the Android SDK Tools. If such dependencies exist, you will need to
 update the SDK Tools package of the SDK after installing the new revision of
 ADT. To update the SDK Tools package, use the Android SDK Manager, as
-described in <a href="{@docRoot}sdk/exploring.html">Exploring the SDK</a>.</p>
+described in <a href="{@docRoot}sdk/installing/adding-packages.html">Adding SDK Packages</a>.</p>
 
 <p>To learn about new features of each ADT revision and also any dependencies on
-the SDK Tools, see the listings in the <a href="#notes">Revisions</a>
+the SDK Tools, see the listings in the <a href="{@docRoot}tools/revisions/index.html">Revisions</a>
 section. To determine the version currently installed, open the
 Eclipse Installed Software window using <strong>Help</strong>
 &gt; <strong>Software Updates</strong> and refer to the version listed for
@@ -568,5 +535,6 @@
 
 
 <p>If you encounter problems during the update, remove the existing ADT plugin from Eclipse, then
-perform a fresh installation, using the instructions for <a href="#installing">Installing the ADT
+perform a fresh installation, using the instructions for <a
+href="{@docRoot}sdk/installing/installing-adt.html">Installing the ADT
 Plugin</a>.</p>
diff --git a/docs/html/tools/help/monkey.jd b/docs/html/tools/help/monkey.jd
index b6300a7..941f5d9 100644
--- a/docs/html/tools/help/monkey.jd
+++ b/docs/html/tools/help/monkey.jd
@@ -12,7 +12,7 @@
 <a name="overview"></a>
 <h2>Overview</h2>
 
-<p>The Monkey is a command-line tool that that you can run on any emulator
+<p>The Monkey is a command-line tool that you can run on any emulator
 instance or on a device.  It sends a pseudo-random stream of 
 user events into the system, which acts as a stress test on the application software you are 
 developing.</p>
diff --git a/docs/html/tools/help/uiautomator/UiSelector.jd b/docs/html/tools/help/uiautomator/UiSelector.jd
index 6d5b4e4..7084540 100644
--- a/docs/html/tools/help/uiautomator/UiSelector.jd
+++ b/docs/html/tools/help/uiautomator/UiSelector.jd
@@ -1915,7 +1915,7 @@
     <div class="jd-details-descr">
 
   <div class="jd-tagdata jd-tagdescr"><p>Set the search criteria to match the resource ID
- of the widget, using a regular expression.http://blog.bettersoftwaretesting.com/</p></div>
+ of the widget, using a regular expression.</p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">Parameters</h5>
       <table class="jd-tagtable">
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index 4afdf132..593770a 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -1,4 +1,5 @@
-page.title=Build Tools
+page.title=SDK Build Tools Release Notes
+
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index ef8575a..a73be5e 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -1,4 +1,5 @@
-page.title=Platforms
+page.title=SDK Platforms Release Notes
+
 @jd:body
 
 <div id="qv-wrapper">
@@ -20,10 +21,16 @@
 
 
 
-<p>This document provides information about Android platform releases. In order to compile your
-application against a particular platform release, you must download and install the SDK Platform
-for that release. If you want to test your application on an emulator, you must also download at
-least one system image for that platform release.</p>
+<p>This document provides release information about the SDK Platform packages required
+for app development. If you want details about the features and APIs added in each Android
+version, instead read the highlights in the <a href="{@docRoot}about/index.html">About</a>
+section.</p>
+
+<p>In order to compile your application against a particular version of Android, you must use the
+<a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> to download and install the SDK
+Platform for that release. If you want to test your application on an emulator, you must also
+download at least one System Image for that Android version.</p>
+
 
 <p>Each platform release includes system images that support a specific processor architecture,
 such as ARM EABI, Intel x86 or MIPS. Platform releases also include a system image that contains
@@ -44,7 +51,7 @@
 <p class="caution"><strong>Important:</strong> To download the most recent Android
 system components from the Android SDK Manager, you must first update the SDK Tools to the
 most recent release and restart the SDK Manager. If you do not, the latest Android system
-components will not be available for download.</p>
+packages may not be available for download.</p>
 
 
 <h2 id="5.0">Android 5.0</h2>
@@ -52,12 +59,30 @@
 <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 2</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Updated layouts in the Support Library and fixed various issues.</p>
+    <p>Dependencies:</p>
+    <ul>
+      <li>Android SDK Platform-tools r21 or higher is required.</li>
+      <li>Android SDK Tools 23.0.5 or higher is required.</li>
+    </ul>
+  </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 1</a> <em>(October 2014)</em>
   </p>
 
   <div class="toggle-content-toggleme">
 
     <p>Initial release for Android 5.0 (API level 21).</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-5.0.html">Android 5.0 APIs overview</a>.</p>
     <p>Dependencies:</p>
     <ul>
       <li>Android SDK Platform-tools r21 or higher is required.</li>
@@ -82,7 +107,7 @@
 
 <div class="toggle-content open">
   <p><a href="#" onclick="return toggleContent(this)">
-    <img src="{@docRoot}assets/images/triangle-open.png"
+    <img src="{@docRoot}assets/images/triangle-closed.png"
 class="toggle-content-img" alt="" />Revision 2</a> <em>(October 2014)</em>
   </p>
 
@@ -135,6 +160,8 @@
   <div class="toggle-content-toggleme">
 
     <p>Maintenance release. The system version is 4.4.2.</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-4.4.html">Android 4.4 APIs overview</a>.</p>
     <dl>
       <dt>Dependencies:</dt>
       <dd>Android SDK Platform-tools r19 or higher is required.</dd>
@@ -153,6 +180,8 @@
   <div class="toggle-content-toggleme">
 
     <p>Initial release. The system version is 4.4.</p>
+    <p>Also see the
+    <a href="{@docRoot}about/versions/android-4.4.html">Android 4.4 APIs overview</a>.</p>
     <dl>
       <dt>Dependencies:</dt>
       <dd>Android SDK Platform-tools r19 or higher is required.</dd>
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index 523929d..3806933 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -1,4 +1,4 @@
-page.title=Android Studio Revisions
+page.title=Android Studio Release Notes
 
 @jd:body
 
@@ -26,7 +26,7 @@
 <li>A version of the Android system image for the emulator</li>
 </ul>
 
-<p>For an introduction to Android Studio, make sure to read the
+<p>For an introduction to Android Studio, read the
 <a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.</p>
 
 <p>Periodic updates are pushed to Android Studio without requiring you to update from here. To
@@ -39,9 +39,32 @@
 <p>The sections below provide notes about successive releases of
 Android Studio, as denoted by revision number. </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=""/>Android Studio v1.0.1</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+    <p>Various fixes and enhancements:</p>
+    <ul>
+      <li>Fixed AVD Manager and <strong>device.xml</strong> file lock issue. </li>
+      <li>Fixed the emulator log on Windows systems. </li>
+      <li>Fixed issue with creating AVDs with Android Studio and Android SDK installed on different
+      drives on Windows systems.</li>
+      <li>Sets the default update channel for new downloads to <strong>Stable</strong>. If you
+      installed the 1.0.0 version of Android Studio and would like stable, production-ready version
+      updates, use <strong>File > Settings > Updates</strong> to change to the <strong>Stable</strong>
+      update channel.
+      </li>
+  </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=""/>Android Studio v1.0</a> <em>(December 2014)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index deafed5..c3a4dea 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -1,4 +1,4 @@
-page.title=ADT Plugin
+page.title=ADT Plugin Release Notes
 
 @jd:body
 
@@ -15,29 +15,25 @@
 </div>
 
 <p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
-that is designed to give you a powerful, integrated environment in which
-to build Android applications.</p>
-
-<p>ADT extends the capabilities of Eclipse to let you quickly set up new Android
+that extends the capabilities of Eclipse to let you quickly set up new Android
 projects, create an application UI, add packages based on the Android
 Framework API, debug your applications using the Android SDK tools, and even
 export signed (or unsigned) {@code .apk} files in order to distribute your application.</p>
 
-<p>Developing in Eclipse with ADT is highly recommended and is the fastest way
-to get started. With the guided project setup it provides, as well as tools
-integration, custom XML editors, and debug output pane, ADT gives you an
-incredible boost in developing Android applications. </p>
+<p class="note"><strong>Note:</strong>
+If you have been using Eclipse with ADT, be aware that <a
+href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
+for Android, so you should migrate to Android Studio to receive all the
+latest IDE updates. For help moving projects,
+see <a href="/sdk/installing/migrate.html">Migrating to Android
+Studio</a>.</p>
 
-<p>This document provides step-by-step instructions on how to download the ADT
-plugin and install it into your Eclipse development environment. Note that
+<p>Note that
 before you can install or use ADT, you must have compatible versions of both the
 Eclipse IDE and the Android SDK installed. For details, make sure to read <a
 href="{@docRoot}sdk/installing/installing-adt.html">Installing the Eclipse
 Plugin</a>. </p>
 
-<p>If you are already using ADT, this document also provides instructions on
-how to update ADT to the latest version or how to uninstall it, if necessary.
-</p>
 
 <p>For information about the features provided by the ADT plugin, such as code
 editor features, SDK tool integration, and the graphical layout editor (for drag-and-drop layout
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 6b3a0a9..11e3ec7 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -1,19 +1,15 @@
-page.title=SDK Tools
+page.title=SDK Tools Release Notes
 excludeFromSuggestions=true
 @jd:body
 
 <p>SDK Tools is a downloadable component for the Android SDK. It includes the
-complete set of development and debugging tools for the Android SDK.</p>
-
-<p>If you are new to the Android SDK, the <a
-href="{@docRoot}sdk/index.html">SDK starter package</a> installs the
-latest revision of the SDK Tools in the <code>&lt;sdk&gt;/tools</code> directory.</p>
+complete set of development and debugging tools for the Android SDK. It is included
+with <a href="{@docRoot}tools/studio/index.html">Android Studio</a>.</p>
 
 <p>If you are already using the SDK and you want to update to the latest version
-of the SDK Tools, use the <em>Android SDK Manager</em> to get the
-update, rather than downloading a new SDK starter package. For more information
-about how to update, see <a
-href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>.</p>
+of the SDK Tools, use the <a
+href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> to get the
+update.</p>
 
 
 <h2 id="notes">Revisions</h2>
@@ -29,6 +25,33 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 24.0.1</a> <em>(December 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 19 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed Java detection issue on 32-bit Windows systems.</li>
+      </ul>
+    </dd>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 24.0.0</a> <em>(December 2014)</em>
   </p>
 
@@ -53,6 +76,7 @@
 </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"
@@ -874,7 +898,7 @@
             <li>Added a flag that sets <em>jumbo mode</em> for DEX files, which allows a larger
               number of strings in the DEX files. Enable this mode by adding the following line to
               the {@code project.properties} file of your project:
-              <pre>set dex.force.jumbo=true</pre></li>
+              <pre>dex.force.jumbo=true</pre></li>
             <li>Improved the build time by pre-dexing libraries (both JAR files and library
               projects).</li>
             <li>Updated the build to generate {@code R} resource classes for library projects
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 1b9dd18..5b36d5d 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -1,4 +1,4 @@
-page.title=Android Studio
+page.title=Android Studio Overview
 @jd:body
 
 <div id="qv-wrapper">
@@ -44,7 +44,7 @@
   <li>And much more</li>
 </ul>
 
-<p><b><a href="{@docRoot}tools/sdk/index.html">Download Android Studio now</a></b>. </p>
+<p><b><a href="{@docRoot}sdk/index.html">Download Android Studio now</a></b>. </p>
 
 <p>If you're new to Android Studio or the IntelliJ IDEA interface, this
 page provides an introduction to some key Android
@@ -102,9 +102,8 @@
 
 
 <h3>New Project and Directory Structure</h3>
-<p>When you use the <em>Project</em> view of a new project in Android Studio or
-(<a href="{@docRoot}tools/eclipse/migrate-adt.html"> a project migrated from Eclipse</a>), you
-should notice that the project structure appears different than you may be used to. Each
+<p>When you use the <em>Project</em> view of a new project in Android Studio, you
+should notice that the project structure appears different than you may be used to in Eclipse. Each
 instance of Android Studio contains a project with one or more application modules. Each
 application module folder contains the complete source sets for that module, including
 {@code src/main} and {@code src/androidTest} directories, resources, build
@@ -115,8 +114,9 @@
     <p>  <img src="{@docRoot}images/tools/studio-project-layout.png" alt="" /></p>
     <p>  <class="img-caption"><strong>Figure 3.</strong> Android Studio project structure</p>
 
-<p>For more information, see <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project +Organization"class="external-link">IntelliJ project organization</a> and
-<a href="{@docRoot}tools/workflow/project/index.html">Managing Projects</a>.</p>
+<p>For more information, see
+<a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project+Organization"class="external-link">IntelliJ project organization</a> and
+<a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.</p>
 
 
 <h3>Creating new files</h3>
@@ -235,8 +235,8 @@
 
 <p>The AVD Manager comes with emulators for Nexus 6 and Nexus 9 devices and also supports
 creating custom Android device skins based on specific emulator properties and assigning those
-skins to hardware profiles. Android Studio installs the the Intel x86 Emulator Accelerator (HAXM)
-and creates a default emulator for quick app prototyping.</p>
+skins to hardware profiles. Android Studio installs the Intel&#174; x86 Hardware Accelerated Execution
+Manager (HAXM) emulator accelerator and creates a default emulator for quick app prototyping.</p>
 
 <p>For more information, see <a href="{@docRoot}tools/devices/managing-avds.html">Managing AVDs</a>.</p>
 
@@ -334,11 +334,11 @@
 <p>An updated installation and setup wizards walk you through a step-by-step installation
 and setup process as the wizard checks for system requirements, such as the Java Development
 Kit (JDK) and available RAM, and then prompts for optional installation options, such as the
-Intel &#174; HAXM accelerator.</p>
+Intel&#174; HAXM emulator accelerator.</p>
 
 <p>An updated setup wizard walks you through the setup processes as
 the wizard updates your system image and emulation requirements, such GPU, and then creates
-an optimized default Android Virtual Device (AVD) based on Android 5 (Lollipop) for speedie and
+an optimized default Android Virtual Device (AVD) based on Android 5 (Lollipop) for speedy and
 reliable emulation. </p>
 <p><img src="{@docRoot}images/tools/studio-setup-wizard.png" /></p>
 <p class="img-caption"><strong>Figure 8.</strong> Setup Wizard</p>
@@ -377,7 +377,7 @@
   the test of time. They are updated roughly bi-weekly or monthly.</li>
   <li><strong>Beta channel</strong>: Beta builds are used for beta-quality releases before a
   production release.</li>
-  <li><strong>Stable channel</strong>: Used for stable, production-read versions.</li>
+  <li><strong>Stable channel</strong>: Used for stable, production-ready versions.</li>
 </ul>
 </p>
 
@@ -386,7 +386,7 @@
 
 
 
-<h2 id="other">Other Highlights/h2>
+<h2 id="other">Other Highlights</h2>
 
 <h3> Translation Editor</h3>
 <p>Multi-language support is enhanced with the Translation Editor plugin so you can easily add
@@ -414,5 +414,5 @@
 <p>Clicking <strong>Import Samples</strong> from the <strong>File</strong> menu or Welcome page
 provides seamless access to Google code samples on GitHub.</p>
     <p><img src="{@docRoot}images/tools/studio-samples-githubaccess.png" /></p>
-    <p class="img-caption"><strong>Figure 12.</strong> Code Sample Access/p>
+    <p class="img-caption"><strong>Figure 12.</strong> Code Sample Access</p>
 
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a8c588a..9437c1b 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -122,7 +122,7 @@
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div>
     <ul>
-      <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects.html"><span class="en">From Eclipse with ADT</span></a></li>
+      <li><a href="<?cs var:toroot ?>tools/debugging/debugging-studio.html"><span class="en">From Android Studio</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects-cmdline.html"><span class="en">From Other IDEs</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/ddms.html"><span class="en">Using DDMS</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/debugging/debugging-log.html"><span class="en">Reading and Writing Logs</span></a></li>
@@ -145,27 +145,12 @@
     </ul>
   </li>
 
-  <li class="nav-section">
-    <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/support-library/index.html"><span
-class="en">Support Library</span></a></div>
-    <ul>
-      <li><a href="<?cs var:toroot ?>tools/support-library/features.html">Features</a></li>
-      <li><a href="<?cs var:toroot ?>tools/support-library/setup.html">Setup</a></li>
-    </ul>
-  </li>
 
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span
 class="en">Tools Help</span></a></div>
     <ul>
       <li><a href="<?cs var:toroot ?>tools/help/adb.html">adb</a></li>
-      <li class="nav-section">
-        <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/adt.html">ADT</a></div>
-        <ul>
-          <li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
-              <span class="en">Installing the Eclipse Plugin</span></a></li>
-        </ul>
-      </li>
       <li><a href="<?cs var:toroot ?>tools/help/android.html">android</a></li>
       <li><a href="<?cs var:toroot ?>tools/help/avd-manager.html">AVD Manager</a></li>
       <li><a href="<?cs var:toroot ?>tools/help/bmgr.html">bmgr</a>
@@ -262,10 +247,10 @@
         <span class="en">SDK Tools</span>
       </a></li>
       <li><a href="<?cs var:toroot ?>tools/revisions/build-tools.html">
-        <span class="en">Build Tools</span>
+        <span class="en">SDK Build Tools</span>
       </a></li>
       <li><a href="<?cs var:toroot ?>tools/revisions/platforms.html">
-        <span class="en">Platforms</span></a></li>
+        <span class="en">SDK Platforms</span></a></li>
       <li><a href="<?cs var:toroot ?>tools/sdk/eclipse-adt.html">
         <span class="en">ADT Plugin</span></a></li>
     </ul>
@@ -293,11 +278,13 @@
 
   <li class="nav-section">
     <div class="nav-section-header">
-    <a href="<?cs var:toroot ?>tools/eclipse/index.html">
+    <a href="<?cs var:toroot ?>tools/help/adt.html">
       <span class="en">Eclipse with ADT</span></a>
     </div>
     <ul>
     <li><a href="<?cs var:toroot ?>sdk/installing/migrate.html">Migrating to Android Studio</a></li>
+    <li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
+        <span class="en">Installing the Eclipse Plugin</span></a></li>
     <li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html">Managing Projects</a></li>
     <li><a href="<?cs var:toroot ?>tools/building/building-eclipse.html">Building and Running</a></li>
     <li><a href="<?cs var:toroot ?>tools/building/building-cmdline-ant.html">Building with Ant</a></li>
diff --git a/docs/html/tools/workflow/index.jd b/docs/html/tools/workflow/index.jd
index f76df75..6a114c7 100644
--- a/docs/html/tools/workflow/index.jd
+++ b/docs/html/tools/workflow/index.jd
@@ -1,9 +1,9 @@
-page.title=Introduction
+page.title=Developer Workflow
 @jd:body
 
-<p>To develop apps for Android devices, you use a set of tools that are included in the Android SDK.
-Once you've downloaded Android Studio and the Android SDK tools you can access these tools directly.
-You can also access most of the SDK tools from the command line. Developing with Android Studio is the
+<p>To develop apps for Android, you use a set of tools that are included in Android Studio.
+In addition to using the tools from Android Studio,
+you can also access most of the SDK tools from the command line. Developing with Android Studio is the
 preferred method because it can directly invoke the tools that you need while developing applications.</p>
 
 <p>However, you may choose to develop with another IDE or a simple text editor and invoke the
diff --git a/docs/html/training/basics/actionbar/adding-buttons.jd b/docs/html/training/basics/actionbar/adding-buttons.jd
index 26c9d0e..40d0bd1 100644
--- a/docs/html/training/basics/actionbar/adding-buttons.jd
+++ b/docs/html/training/basics/actionbar/adding-buttons.jd
@@ -1,4 +1,6 @@
 page.title=Adding Action Buttons
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/index.jd b/docs/html/training/basics/actionbar/index.jd
index 0303043..6a8eaff 100644
--- a/docs/html/training/basics/actionbar/index.jd
+++ b/docs/html/training/basics/actionbar/index.jd
@@ -1,5 +1,6 @@
 page.title=Adding the Action Bar
 page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/actionbar/overlaying.jd b/docs/html/training/basics/actionbar/overlaying.jd
index 800cd44..634534e 100644
--- a/docs/html/training/basics/actionbar/overlaying.jd
+++ b/docs/html/training/basics/actionbar/overlaying.jd
@@ -1,4 +1,6 @@
 page.title=Overlaying the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/setting-up.jd b/docs/html/training/basics/actionbar/setting-up.jd
index 158ce92..bccbd04 100644
--- a/docs/html/training/basics/actionbar/setting-up.jd
+++ b/docs/html/training/basics/actionbar/setting-up.jd
@@ -1,4 +1,6 @@
 page.title=Setting Up the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/actionbar/styling.jd b/docs/html/training/basics/actionbar/styling.jd
index 4128a97..7c63952 100644
--- a/docs/html/training/basics/actionbar/styling.jd
+++ b/docs/html/training/basics/actionbar/styling.jd
@@ -1,4 +1,6 @@
 page.title=Styling the Action Bar
+page.tags=actionbar
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/data-storage/databases.jd b/docs/html/training/basics/data-storage/databases.jd
index 6ea2140..4a91d0d 100644
--- a/docs/html/training/basics/data-storage/databases.jd
+++ b/docs/html/training/basics/data-storage/databases.jd
@@ -1,8 +1,8 @@
 page.title=Saving Data in SQL Databases
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
-previous.title=Saving Data in Files
-previous.link=files.html
 
 @jd:body
 
diff --git a/docs/html/training/basics/data-storage/files.jd b/docs/html/training/basics/data-storage/files.jd
index 52bea4c..49a9169 100644
--- a/docs/html/training/basics/data-storage/files.jd
+++ b/docs/html/training/basics/data-storage/files.jd
@@ -1,4 +1,6 @@
 page.title=Saving Files
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/data-storage/index.jd b/docs/html/training/basics/data-storage/index.jd
index fc0c8b5..aa223f6 100644
--- a/docs/html/training/basics/data-storage/index.jd
+++ b/docs/html/training/basics/data-storage/index.jd
@@ -1,5 +1,6 @@
 page.title=Saving Data
 page.tags=data storage,files,sql,database,preferences
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/data-storage/shared-preferences.jd b/docs/html/training/basics/data-storage/shared-preferences.jd
index a6717c4..debb17d 100644
--- a/docs/html/training/basics/data-storage/shared-preferences.jd
+++ b/docs/html/training/basics/data-storage/shared-preferences.jd
@@ -1,4 +1,6 @@
 page.title=Saving Key-Value Sets
+page.tags=data storage
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
index f0024e2..059a1e9 100644
--- a/docs/html/training/location/index.jd
+++ b/docs/html/training/location/index.jd
@@ -67,9 +67,10 @@
 <h2>Lessons</h2>
 <dl>
   <dt>
-    <b><a href="retrieve-current.html">Retrieving the Current Location</a></b>
+    <b><a href="retrieve-current.html">Getting the Last Known Location</a></b>
   </dt> <dd>
-     Learn how to retrieve the user's current location.
+     Learn how to retrieve the last known location of an Android device, which
+     is usually equivalent to the user's current location.
   </dd> <dt>
     <b><a href="receive-location-updates.html">Receiving Location
     Updates</a></b>
diff --git a/docs/html/training/location/retrieve-current.jd b/docs/html/training/location/retrieve-current.jd
index f079040..5bac3fa 100644
--- a/docs/html/training/location/retrieve-current.jd
+++ b/docs/html/training/location/retrieve-current.jd
@@ -1,386 +1,162 @@
-page.title=Retrieving the Current Location
+page.title=Getting the Last Known Location
 trainingnavtop=true
 @jd:body
+
 <div id="tb-wrapper">
-<div id="tb">
+  <div id="tb">
 
-<h2>This lesson teaches you to</h2>
-<ol>
-    <li><a href="#AppPermissions">Specify App Permissions</a></li>
-    <li><a href="#CheckServices">Check for Google Play services</a></li>
-    <li><a href="#DefineCallbacks">Define Location Services Callbacks</a></li>
-    <li><a href="#ConnectClient">Connect the Location Client</a></li>
-    <li><a href="#GetLocation">Get the Current Location</a></li>
-</ol>
+    <h2>This lesson teaches you how to</h2>
+    <ol>
+      <li><a href="#setup">Set Up Google Play Services</a></li>
+      <li><a href="#permissions">Specify App Permissions</a></li>
+      <li><a href="#play-services">Connect to Google Play Services</a></li>
+      <li><a href="#last-known">Get the Last Known Location</a></li>
+    </ol>
 
-<h2>You should also read</h2>
-<ul>
-    <li>
-        <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
-    </li>
-</ul>
+    <h2>You should also read</h2>
+    <ul>
+      <li>
+        <a href="{@docRoot}google/play-services/setup.html">Setting up Google Play
+        Services</a>
+      </li>
+    </ul>
 
-<h2>Try it out</h2>
-
-<div class="download-box">
-  <a href="http://developer.android.com/shareables/training/LocationUpdates.zip" class="button">Download the sample</a>
-  <p class="filename">LocationUpdates.zip</p>
+    <h2>Try it out</h2>
+    <ul>
+      <li>
+        <a href="https://github.com/googlesamples/android-play-location/tree/master/BasicLocationSample" class="external-link">BasicLocationSample</a>
+      </li>
+    </ul>
+  </div>
 </div>
 
-</div>
-</div>
+<p>Using the Google Play services location APIs, your app can request the last
+  known location of the user's device. In most cases, you are interested in the
+  user's current location, which is usually equivalent to the last known
+  location of the device.</p>
 
-<p>
-    Location Services automatically maintains the user's current location, so all your app has to do
-    is retrieve it as needed. The location's accuracy is based on the location permissions you've
-    requested and location sensors that are currently active for the device.
-<p>
-    Location Services sends the current location to your app through a location client, which is
-    an instance of the Location Services class
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html">LocationClient</a></code>.
-    All requests for location information go through this client.
-</p>
-<p class="note">
-    <strong>Note:</strong> Before you start the lesson, be sure that your development environment
-    and test device are set up correctly. To learn more about this, read the
-    <a href="{@docRoot}google/play-services/setup.html">Setup</a> section in the Google Play
-    services guide.
-</p>
-<!--
-    Specify App Permissions
- -->
-<h2 id="AppPermissions">Specify App Permissions</h2>
-<p>
-    Apps that use Location Services must request location permissions. Android has two location
-    permissions: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}
-    and {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. The
-    permission you choose controls the accuracy of the current location. If you request only coarse
-    location permission, Location Services obfuscates the returned location to an accuracy
-    that's roughly equivalent to a city block.
-</p>
-<p>
-    Requesting {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} implies
-    a request for {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}.
-</p>
-<p>
-    For example, to add {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
-    ACCESS_COARSE_LOCATION}, insert the following as a child element of the
-    <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
-    element:
-</p>
-<pre>
-&lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&gt;
-</pre>
-<!--
-    Check for Google Play Services
- -->
-<h2 id="CheckServices">Check for Google Play Services</h2>
-<p>
-    Location Services is part of the Google Play services APK. Since it's hard to anticipate the
-    state of the user's device, you should always check that the APK is installed before you attempt
-    to connect to Location Services. To check that the APK is installed, call
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#isGooglePlayServicesAvailable(android.content.Context)">GooglePlayServicesUtil.isGooglePlayServicesAvailable()</a></code>,
-    which returns one of the
-    integer result codes listed in the reference documentation for
-<code><a href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html">ConnectionResult</a></code>.
-    If you encounter an error, call
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getErrorDialog(int, android.app.Activity, int)">GooglePlayServicesUtil.getErrorDialog()</a></code>
-    to retrieve localized dialog that prompts users to take the correct action, then display
-    the dialog in a {@link android.support.v4.app.DialogFragment}. The dialog may allow the
-    user to correct the problem, in which case Google Play services may send a result back to your
-    activity. To handle this result, override the method
-    {@link android.support.v4.app.FragmentActivity#onActivityResult onActivityResult()}.
-</p>
-<p>
-    Since you usually need to check for Google Play services in more than one place in your code,
-    define a method that encapsulates the check, then call the method before each connection
-    attempt. The following snippet contains all of the code required to check for Google
-    Play services:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity {
-    ...
-    // Global constants
-    /*
-     * Define a request code to send to Google Play services
-     * This code is returned in Activity.onActivityResult
-     */
-    private final static int
-            CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
-    ...
-    // Define a DialogFragment that displays the error dialog
-    public static class ErrorDialogFragment extends DialogFragment {
-        // Global field to contain the error dialog
-        private Dialog mDialog;
-        // Default constructor. Sets the dialog field to null
-        public ErrorDialogFragment() {
-            super();
-            mDialog = null;
-        }
-        // Set the dialog to display
-        public void setDialog(Dialog dialog) {
-            mDialog = dialog;
-        }
-        // Return a Dialog to the DialogFragment.
-        &#64;Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return mDialog;
-        }
-    }
-    ...
-    /*
-     * Handle results returned to the FragmentActivity
-     * by Google Play services
-     */
-    &#64;Override
-    protected void onActivityResult(
-            int requestCode, int resultCode, Intent data) {
-        // Decide what to do based on the original request code
-        switch (requestCode) {
-            ...
-            case CONNECTION_FAILURE_RESOLUTION_REQUEST :
-            /*
-             * If the result code is Activity.RESULT_OK, try
-             * to connect again
-             */
-                switch (resultCode) {
-                    case Activity.RESULT_OK :
-                    /*
-                     * Try the request again
-                     */
-                    ...
-                    break;
-                }
-            ...
-        }
-     }
-    ...
-    private boolean servicesConnected() {
-        // Check that Google Play services is available
-        int resultCode =
-                GooglePlayServicesUtil.
-                        isGooglePlayServicesAvailable(this);
-        // If Google Play services is available
-        if (ConnectionResult.SUCCESS == resultCode) {
-            // In debug mode, log the status
-            Log.d("Location Updates",
-                    "Google Play services is available.");
-            // Continue
-            return true;
-        // Google Play services was not available for some reason.
-        // resultCode holds the error code.
-        } else {
-            // Get the error dialog from Google Play services
-            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
-                    resultCode,
-                    this,
-                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
+<p>Specifically, use the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html">fused
+  location provider</a> to retrieve the device's last known location. The fused
+  location provider is one of the location APIs in Google Play services. It
+  manages the underlying location technology and provides a simple API so that
+  you can specify requirements at a high level, like high accuracy or low power.
+  It also optimizes the device's use of battery power.</p>
 
-            // If Google Play services can provide an error dialog
-            if (errorDialog != null) {
-                // Create a new DialogFragment for the error dialog
-                ErrorDialogFragment errorFragment =
-                        new ErrorDialogFragment();
-                // Set the dialog in the DialogFragment
-                errorFragment.setDialog(errorDialog);
-                // Show the error dialog in the DialogFragment
-                errorFragment.show(getSupportFragmentManager(),
-                        "Location Updates");
-            }
-        }
-    }
-    ...
-}
-</pre>
-<p>
-    Snippets in the following sections call this method to verify that Google Play services is
-    available.
-</p>
-<!--
-    Define Location Services Callbacks
- -->
-<h2 id="DefineCallbacks">Define Location Services Callbacks</h2>
-<p>
-    To get the current location, create a location client, connect it
-    to Location Services, and then call its
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#getLastLocation()">getLastLocation()</a></code>
-    method. The return value  is the best, most recent location, based on the permissions your
-    app requested and the currently-enabled location sensors.
-<p>
-<p>
-    Before you create the location client, implement the interfaces that Location Services uses to
-    communicate with your app:
-</p>
-<dl>
-    <dt>
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html">ConnectionCallbacks</a></code>
-    </dt>
-    <dd>
-        Specifies methods that Location Services calls when a location client is connected or
-        disconnected.
-    </dd>
-    <dt>
-<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.OnConnectionFailedListener.html">OnConnectionFailedListener</a></code>
-    </dt>
-    <dd>
-        Specifies a method that Location Services calls if an error occurs while attempting to
-        connect the location client. This method uses the previously-defined {@code showErrorDialog}
-        method to display an error dialog that attempts to fix the problem using Google Play
-        services.
-    </dd>
-</dl>
-<p>
-    The following snippet shows how to specify the interfaces and define the methods:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
-    ...
-    /*
-     * Called by Location Services when the request to connect the
-     * client finishes successfully. At this point, you can
-     * request the current location or start periodic updates
-     */
-    &#64;Override
-    public void onConnected(Bundle dataBundle) {
-        // Display the connection status
-        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
+<p>This lesson shows you how to make a single request for the location of a
+  device using the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method in the fused location provider.
 
-    }
+<h2 id="setup">Set Up Google Play Services</h2>
+
+<p>To access the fused location provider, your app's development project must
+  include Google Play services. Download and install the Google Play services
+  component via the <a href="{@docRoot}tools/help/sdk-manager.html">SDK
+  Manager</a> and add the library to your project. For details, see the guide to
+  <a href="{@docRoot}google/play-services/setup.html">Setting Up Google Play
+  Services</a>.</p>
+
+<h2 id="permissions">Specify App Permissions</h2>
+
+<p>Apps that use location services must request location permissions. Android
+  offers two location permissions:
+  {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION}
+  and
+  {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}.
+  The permission you choose determines the accuracy of the location returned by
+  the API. If you specify
+  {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION},
+  the API returns a location with an accuracy approximately equivalent to a city
+  block.</p>
+
+<p>This lesson requires only coarse location. Request this permission with the
+  {@code uses-permission} element in your app manifest, as shown in the
+  following example:
+
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.gms.location.sample.basiclocationsample" &gt;
+  
+  &lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&gt;
+&lt;/manifest&gt;
+</pre>
+
+<h2 id="play-services">Connect to Google Play Services</h2>
+
+<p>To connect to the API, you need to create an instance of the
+  Google Play services API client. For details about using the client, see
+  the guide to
+  <a href="{@docRoot}google/auth/api-client.html#Starting">Accessing Google
+  APIs</a>.
+</p>
+
+<p>In your activity's {@link android.app.Activity#onCreate onCreate()} method,
+  create an instance of Google API Client using
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html">{@code GoogleApiClient.Builder}</a>.
+  Use the builder to add the
+  <a href="{@docRoot}reference/com/google/android/gms/location/LocationServices.html">{@code LocationServices}</a>
+  API.</p>
+
+<p>The sample app defines a {@code buildGoogleApiClient()} method, called from
+  the activity's {@link android.app.Activity#onCreate onCreate()} method,
+  which includes the following code.</p>
+
+<pre>
+protected synchronized void buildGoogleApiClient() {
+    mGoogleApiClient = new GoogleApiClient.Builder(this)
+        .addConnectionCallbacks(this)
+        .addOnConnectionFailedListener(this)
+        .addApi(LocationServices.API)
+        .build();
+}
+</pre>
+
+<h2 id="last-known">Get the Last Known Location</h2>
+
+<p>Once you have connected to Google Play services and the location services
+  API, you can get the last known location of a user's device. When your app is
+  connected to these you can use the fused location provider's
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method to retrieve the device location. The precision of the location returned
+  by this call is determined by the permission setting you put in your app
+  manifest, as described in the <a href="#permissions">Specify App
+  Permissions</a> section of this document.</p>
+
+<p>To request the last known location, call the
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method, passing it your instance of the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>
+  object. Do this in the
+  <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a>
+  callback provided by Google API Client, which is called when the client is
+  ready. The following code sample illustrates the request and a simple
+  handling of the response:</p>
+
+<pre>
+public class MainActivity extends ActionBarActivity implements
+        ConnectionCallbacks, OnConnectionFailedListener {
     ...
-    /*
-     * Called by Location Services if the connection to the
-     * location client drops because of an error.
-     */
     &#64;Override
-    public void onDisconnected() {
-        // Display the connection status
-        Toast.makeText(this, "Disconnected. Please re-connect.",
-                Toast.LENGTH_SHORT).show();
-    }
-    ...
-    /*
-     * Called by Location Services if the attempt to
-     * Location Services fails.
-     */
-    &#64;Override
-    public void onConnectionFailed(ConnectionResult connectionResult) {
-        /*
-         * Google Play services can resolve some errors it detects.
-         * If the error has a resolution, try sending an Intent to
-         * start a Google Play services activity that can resolve
-         * error.
-         */
-        if (connectionResult.hasResolution()) {
-            try {
-                // Start an Activity that tries to resolve the error
-                connectionResult.startResolutionForResult(
-                        this,
-                        CONNECTION_FAILURE_RESOLUTION_REQUEST);
-                /*
-                 * Thrown if Google Play services canceled the original
-                 * PendingIntent
-                 */
-            } catch (IntentSender.SendIntentException e) {
-                // Log the error
-                e.printStackTrace();
-            }
-        } else {
-            /*
-             * If no resolution is available, display a dialog to the
-             * user with the error.
-             */
-            showErrorDialog(connectionResult.getErrorCode());
+    public void onConnected(Bundle connectionHint) {
+        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
+                mGoogleApiClient);
+        if (mLastLocation != null) {
+            mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
+            mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
         }
     }
-    ...
 }
 </pre>
-<!--
-    Connect the Location Client
- -->
-<h2 id="ConnectClient">Connect the Location Client</h2>
-<p>
-    Now that the callback methods are in place, create the location client and connect it to
-    Location Services.
-</p>
-<p>
-    You should create the location client in {@link android.support.v4.app.FragmentActivity#onCreate
-    onCreate()}, then connect it in
-    {@link android.support.v4.app.FragmentActivity#onStart onStart()}, so that Location Services
-    maintains the current location while your activity is fully visible. Disconnect the client in
-    {@link android.support.v4.app.FragmentActivity#onStop onStop()}, so that when your app is not
-    visible, Location Services is not maintaining the current location. Following this pattern of
-    connection and disconnection helps save battery power. For example:
-</p>
-<p class="note">
-    <strong>Note:</strong> The current location is only maintained while a location client is
-    connected to Location Service. Assuming that no other apps are connected to Location Services,
-    if you disconnect the client and then sometime later call
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#getLastLocation()">getLastLocation()</a></code>,
-    the result may be out of date.
-</p>
-<pre>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
-    ...
-    &#64;Override
-    protected void onCreate(Bundle savedInstanceState) {
-        ...
-        /*
-         * Create a new location client, using the enclosing class to
-         * handle callbacks.
-         */
-        mLocationClient = new LocationClient(this, this, this);
-        ...
-    }
-    ...
-    /*
-     * Called when the Activity becomes visible.
-     */
-    &#64;Override
-    protected void onStart() {
-        super.onStart();
-        // Connect the client.
-        mLocationClient.connect();
-    }
-    ...
-    /*
-     * Called when the Activity is no longer visible.
-     */
-    &#64;Override
-    protected void onStop() {
-        // Disconnecting the client invalidates it.
-        mLocationClient.disconnect();
-        super.onStop();
-    }
-    ...
-}
-</pre>
-<!--
-    Get the Current Location
- -->
-<h2 id="GetLocation">Get the Current Location</h2>
-<p>
-    To get the current location, call
-<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#getLastLocation()">getLastLocation()</a></code>.
-    For example:
-</p>
-<pre>
-public class MainActivity extends FragmentActivity implements
-        GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
-    ...
-    // Global variable to hold the current location
-    Location mCurrentLocation;
-    ...
-    mCurrentLocation = mLocationClient.getLastLocation();
-    ...
-}
-</pre>
-<p>
-    The next lesson, <a href="receive-location-updates.html">Receiving Location Updates</a>, shows
-    you how to receive periodic location updates from Location Services.
-</p>
+
+<p>The
+  <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)">{@code getLastLocation()}</a>
+  method returns a
+  <a href="{@docRoot}reference/android/location/Location.html">{@code Location}</a>
+  object from which you can retrieve the latitude and longitude coordinates of a
+  geographic location. The location object returned may be null in rare cases
+  when the location is not available.</p>
+
+<p>The next lesson,
+  <a href="receive-location-updates.html">Receiving Location Updates</a>, shows
+  you how to receive periodic location updates.</p>
diff --git a/docs/html/training/notify-user/build-notification.jd b/docs/html/training/notify-user/build-notification.jd
index 80f2cd5..d24a496 100644
--- a/docs/html/training/notify-user/build-notification.jd
+++ b/docs/html/training/notify-user/build-notification.jd
@@ -1,10 +1,8 @@
 page.title=Building a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Preserving Navigation when Starting an Activity
-next.link=navigation.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/display-progress.jd b/docs/html/training/notify-user/display-progress.jd
index c00576c..3439571 100644
--- a/docs/html/training/notify-user/display-progress.jd
+++ b/docs/html/training/notify-user/display-progress.jd
@@ -1,10 +1,8 @@
 page.title=Displaying Progress in a Notification
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-previous.title=Using Expanded Notification Styles
-previous.link=expanded.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/expanded.jd b/docs/html/training/notify-user/expanded.jd
index a3cc6ad..b657426 100644
--- a/docs/html/training/notify-user/expanded.jd
+++ b/docs/html/training/notify-user/expanded.jd
@@ -1,10 +1,8 @@
 page.title=Using Big View Styles
-Styles parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Displaying Progress in a Notification
-next.link=display-progress.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd
index f7d0f87..616e767 100644
--- a/docs/html/training/notify-user/index.jd
+++ b/docs/html/training/notify-user/index.jd
@@ -1,5 +1,6 @@
 page.title=Notifying the User
 page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/notify-user/managing.jd b/docs/html/training/notify-user/managing.jd
index 4782734..fc12cfb 100644
--- a/docs/html/training/notify-user/managing.jd
+++ b/docs/html/training/notify-user/managing.jd
@@ -1,10 +1,8 @@
 page.title=Updating Notifications
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Creating Expanded Notifications
-next.link=expanded.html
 
 @jd:body
 
diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd
index fc950131..b7051ab 100644
--- a/docs/html/training/notify-user/navigation.jd
+++ b/docs/html/training/notify-user/navigation.jd
@@ -1,10 +1,8 @@
 page.title=Preserving Navigation when Starting an Activity
-parent.title=Notifying the User
-parent.link=index.html
+page.tags=notifications
+helpoutsWidget=true
 
 trainingnavtop=true
-next.title=Updating Notifications
-next.link=managing.html
 
 @jd:body
 
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 7a0e413..2489b91 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -694,7 +694,7 @@
         <ul>
           <li>
             <a href="<?cs var:toroot ?>training/location/retrieve-current.html">
-            Retrieving the Current Location
+            Getting the Last Known Location
             </a>
           </li>
           <li>
@@ -834,6 +834,38 @@
           </li>
         </ul>
       </li>
+
+      <li class="nav-section">
+        <div class="nav-section-header">
+          <a href="<?cs var:toroot ?>training/wearables/watch-faces/index.html"
+             description="How to create watch faces for wearables."
+            >Creating Watch Faces</a>
+        </div>
+        <ul>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/designing.html">Designing Watch Faces</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/service.html">Building a Watch Face Service</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/drawing.html">Drawing Watch Faces</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/information.html">Showing Information in Watch Faces</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/configuration.html">Providing Configuration Activities</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/issues.html">Addressing Common Issues</a>
+          </li>
+          <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/performance.html">Optimizing Performance and Battery Life</a>
+          </li>
+        </ul>
+      </li>
+
       <li>
         <a href="<?cs var:toroot ?>training/articles/wear-location-detection.html"
            description=
diff --git a/docs/html/training/tv/discovery/in-app-search.jd b/docs/html/training/tv/discovery/in-app-search.jd
index 28c7a35..fb7c097 100644
--- a/docs/html/training/tv/discovery/in-app-search.jd
+++ b/docs/html/training/tv/discovery/in-app-search.jd
@@ -1,5 +1,6 @@
 page.title=Searching within TV Apps
-page.tags="leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
index 5849149..f22ca67 100644
--- a/docs/html/training/tv/discovery/index.jd
+++ b/docs/html/training/tv/discovery/index.jd
@@ -1,5 +1,6 @@
 page.title=Helping Users Find Your Content on TV
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 startpage=true
 
diff --git a/docs/html/training/tv/discovery/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
index a6eb152..0f6d256 100644
--- a/docs/html/training/tv/discovery/recommendations.jd
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -1,5 +1,6 @@
 page.title=Recommending TV Content
-page.tags="recommendation","recommend"
+page.tags=tv, recommendations
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
index 5276d7f..371e9e9 100644
--- a/docs/html/training/tv/games/index.jd
+++ b/docs/html/training/tv/games/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Games
-page.tags="tv", "games", "controller"
+page.tags=tv, games, controller
+helpoutsWidget=true
 page.image=images/games/game-controller-buttons_2x_crop.png
 page.metaDescription=How to bring your games to Android TV, including recommendations and examples.
 page.article=true
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
index 9b25166..9c81597 100644
--- a/docs/html/training/tv/playback/browse.jd
+++ b/docs/html/training/tv/playback/browse.jd
@@ -1,5 +1,6 @@
 page.title=Creating a Catalog Browser
-page.tags="browsefragment","presenter","backgroundmanager"
+page.tags=tv, browsefragment, presenter, backgroundmanager
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/playback/details.jd b/docs/html/training/tv/playback/details.jd
index 6391a49..bd6d67a 100644
--- a/docs/html/training/tv/playback/details.jd
+++ b/docs/html/training/tv/playback/details.jd
@@ -1,5 +1,6 @@
 page.title=Building a Details View
-page.tags="detailsfragment"
+page.tags=tv, detailsfragment
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 09c3f24..31c7524 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Playback Apps
-page.tags="tv","leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 
 startpage=true
 
diff --git a/docs/html/training/tv/playback/now-playing.jd b/docs/html/training/tv/playback/now-playing.jd
index b64beb0..e158697 100644
--- a/docs/html/training/tv/playback/now-playing.jd
+++ b/docs/html/training/tv/playback/now-playing.jd
@@ -1,5 +1,6 @@
 page.title=Displaying a Now Playing Card
-page.tags="nowplaying","mediasession"
+page.tags=tv, mediasession
+helpoutsWidget=true
 
 trainingnavtop=true
 
diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd
index fc52602..b25a0dd 100644
--- a/docs/html/training/tv/start/hardware.jd
+++ b/docs/html/training/tv/start/hardware.jd
@@ -1,5 +1,6 @@
 page.title=Handling TV Hardware
-page.tags="unsupported"
+page.tags=tv
+helpoutsWidget=true
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
index fb478a8..54ff2d9 100644
--- a/docs/html/training/tv/start/index.jd
+++ b/docs/html/training/tv/start/index.jd
@@ -1,5 +1,6 @@
 page.title=Building TV Apps
-page.tags="tv", "leanback"
+page.tags=tv, leanback
+helpoutsWidget=true
 startpage=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/layouts.jd b/docs/html/training/tv/start/layouts.jd
index d2abe1d..a390702 100644
--- a/docs/html/training/tv/start/layouts.jd
+++ b/docs/html/training/tv/start/layouts.jd
@@ -1,4 +1,7 @@
 page.title=Building Layouts for TV
+page.tags=tv
+helpoutsWidget=true
+
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/navigation.jd b/docs/html/training/tv/start/navigation.jd
index 1c9faca..a94e3ae 100644
--- a/docs/html/training/tv/start/navigation.jd
+++ b/docs/html/training/tv/start/navigation.jd
@@ -1,5 +1,6 @@
 page.title=Creating TV Navigation
-page.tags="focus","selection","d-pad"
+page.tags=tv, d-pad, focus
+helpoutsWidget=true
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
index aab1a39..e3b92c6 100644
--- a/docs/html/training/tv/start/start.jd
+++ b/docs/html/training/tv/start/start.jd
@@ -1,5 +1,6 @@
 page.title=Get Started with TV Apps
-page.tags="leanback","recyclerview","launcher"
+page.tags=tv, leanback, recyclerview
+helpoutsWidget=true
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
index cde8ba7..9c10850 100644
--- a/docs/html/training/tv/tif/index.jd
+++ b/docs/html/training/tv/tif/index.jd
@@ -1,5 +1,6 @@
 page.title=Building Live TV Apps
-page.tags="tv", "tif"
+page.tags=tv, tif
+helpoutsWidget=true
 page.article=true
 
 @jd:body
diff --git a/docs/html/training/wearables/apps/bt-debugging.jd b/docs/html/training/wearables/apps/bt-debugging.jd
index 7569e7e..beded9e 100644
--- a/docs/html/training/wearables/apps/bt-debugging.jd
+++ b/docs/html/training/wearables/apps/bt-debugging.jd
@@ -1,4 +1,6 @@
 page.title=Debugging over Bluetooth
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd
index 683dd31..c12ffa7 100644
--- a/docs/html/training/wearables/apps/creating.jd
+++ b/docs/html/training/wearables/apps/creating.jd
@@ -1,4 +1,6 @@
 page.title=Creating and Running a Wearable App
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/apps/index.jd b/docs/html/training/wearables/apps/index.jd
index 4bdd6bf..812f893 100644
--- a/docs/html/training/wearables/apps/index.jd
+++ b/docs/html/training/wearables/apps/index.jd
@@ -1,5 +1,6 @@
 page.title=Creating Wearable Apps
-page.tags="wear","wearable","app"
+page.tags=wear
+helpoutsWidget=true
 page.image=wear/images/01_create.png
 
 @jd:body
diff --git a/docs/html/training/wearables/apps/layouts.jd b/docs/html/training/wearables/apps/layouts.jd
index a35acb0..69e57ca 100644
--- a/docs/html/training/wearables/apps/layouts.jd
+++ b/docs/html/training/wearables/apps/layouts.jd
@@ -1,4 +1,6 @@
 page.title=Creating Custom Layouts
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
@@ -116,7 +118,13 @@
     <li><code>CircledImageView</code> - An image view surrounded by a circle.</li>
     <li><code>ConfirmationActivity</code> - An activity that displays confirmation animations after the user
     completes an action.</li>
+    <li><code>CrossFadeDrawable</code> - A drawable that contains two child drawables and provides
+    methods to directly adjust the blend between the two.</li>
+    <li><code>DelayedConfirmationView</code> - A view that provides a circular countdown timer,
+    typically used to automatically confirm an operation after a short delay has elapsed.</li>
     <li><code>DismissOverlayView</code> - A view for implementing long-press-to-dismiss.</li>
+    <li><code>DotsPageIndicator</code> - A page indicator for GridViewPager that identifies the
+    current page in relation to all available pages on the current row.</li>
     <li><code>GridViewPager</code> - A layout manager that allows the user to both vertically and
     horizontally through pages of data. You supply an implementation of a GridPagerAdapter to
     generate the pages that the view shows.</li>
@@ -132,6 +140,18 @@
     </li>
 </ul>
 
-<p class="note"><a href="{@docRoot}shareables/training/wearable-support-docs.zip">Download the full API
-reference documentation</a> for the classes above. The documentation goes over how to use
-each UI widget.</p>
+<h3 id="UiLibReference">Wear UI library API reference</h3>
+
+<p>The reference documentation explains how to use each UI widget in detail. Download the
+<a href="{@docRoot}shareables/training/wearable-support-docs.zip">API reference documentation</a>
+for the classes above.</p>
+
+<h3 id="UiLibEclipse">Download the Wearable UI library for Eclipse ADT</h3>
+
+<p>If you are using the ADT plugin for Eclipse, download the
+<a href="{@docRoot}shareables/training/wearable-support-lib.zip">Wearable UI library</a> to
+include the Wearable UI library as a dependency in your project.</p>
+
+<p class="note"><strong>Note:</strong> We recommend
+<a href="{@docRoot}sdk/index.html">Android Studio</a> for Android Wear app
+development.</p>
diff --git a/docs/html/training/wearables/apps/packaging.jd b/docs/html/training/wearables/apps/packaging.jd
index b538d6e..9c42978 100644
--- a/docs/html/training/wearables/apps/packaging.jd
+++ b/docs/html/training/wearables/apps/packaging.jd
@@ -1,4 +1,6 @@
 page.title=Packaging Wearable Apps
+page.tags=wear
+helpoutsWidget=true
 
 @jd:body
 
@@ -14,7 +16,7 @@
 </div>
 </div>
 
-<p>When publishing to users, you must package a wearable app inside of a handheld app, 
+<p>When publishing to users, you must package a wearable app inside of a handheld app,
 because users cannot browse and install apps directly on the wearable. If packaged properly,
 when users download the handheld app, the system automatically pushes the wearable app to the
 paired wearable.
@@ -29,6 +31,14 @@
 <p>To properly package a wearable app in Android Studio:</p>
 
 <ol>
+  <li>Include all the permissions declared in the manifest file of the wearable app module
+  in the manifest file of the handheld app module. For example, if you specify the {@link
+  android.Manifest.permission#VIBRATE} permission for the wearable app, you must also add that
+  permission to the handheld app.</li>
+
+  <li>Ensure that both the wearable and handheld app modules have the same package name and
+  version number.</li>
+
   <li>Declare a Gradle dependency in the handheld app's <code>build.gradle</code> file
   that points to the wearable app module:
 <pre>
@@ -43,39 +53,21 @@
   to specify your release keystore and sign your app. Android Studio exports the signed
   handheld app with the wearable app embedded in it automatically into your project's root folder.
 
-  <p>Alternatively, you can create a <code>signingConfig</code> rule in the wearable and handheld
-  modules' <code>build.gradle</code> file to sign them with your release key. Both apps must be
-  signed to have the automatic pushing of the wearable app work.
+  <p>Alternatively, you can sign both apps from the command line using the
+  <a href="{@docRoot}sdk/installing/studio-build.html#gradleWrapper">Gradle wrapper</a>. Both apps
+  must be signed to have the automatic pushing of the wearable app work.</p>
 
-<pre>
-android {
-  ...
-  signingConfigs {
-    release {
-      keyAlias 'myAlias'
-      keyPassword 'myPw'
-      storeFile file('path/to/release.keystore')
-      storePassword 'myPw'
-    }
-  }
-  buildTypes {
-    release {
-      ...
-      signingConfig signingConfigs.release
-    }
-  }
-  ...
-}
+  <p>Store your key file location and credentials in environment variables and run the Gradle
+  wrapper as follows:</p>
+
+<pre class="no-pretty-print">
+./gradlew assembleRelease \
+  -Pandroid.injected.signing.store.file=$KEYFILE \
+  -Pandroid.injected.signing.store.password=$STORE_PASSWORD \
+  -Pandroid.injected.signing.key.alias=$KEY_ALIAS \
+  -Pandroid.injected.signing.key.password=$KEY_PASSWORD
 </pre>
-  <p>Build the handheld app by clicking the Gradle button on the right vertical toolbar of
-  Android Studio and running the <b>assembleRelease</b> task. The task is located under
-  <b>Project name > Handheld module name > assembleRelease</b>.
-  </p>
-
-<p class="note"><b>Note:</b>This example embeds the password in your Gradle file, which might be undesirable. See
-<a href="{@docRoot}sdk/installing/studio-build.html#configureSigning">Configure signing settings</a>
-for information about how to create an environment variable for the passwords instead.
-</p>
+ </li>
 </ol>
 
 <h3>Signing the wearable and handheld app separately</h3>
@@ -101,6 +93,12 @@
 </p>
 
 <ol>
+  <li>Include all the permissions declared in the manifest file of the wearable app
+  in the manifest file of the mobile app. For example, if you specify the {@link
+  android.Manifest.permission#VIBRATE} permission for the wearable app, you must also add that
+  permission to the mobile app.</li>
+  <li>Ensure that both the wearable and mobile APKs have the same package name and version
+  number.</li>
   <li>Copy the signed wearable app to your handheld project's <code>res/raw</code> directory. We'll
   refer to the APK as <code>wearable_app.apk</code>.</li>
   <li>Create a <code>res/xml/wearable_app_desc.xml</code> file that contains the version and
@@ -115,8 +113,8 @@
 
 <p>
 The <code>package</code>, <code>versionCode</code>, and <code>versionName</code> are the
-same values specified in the wearable app's <code>AndroidManifest.xml</code> file. 
-The <code>rawPathResId</code> is the static variable name of the APK resource. For example, 
+same values specified in the wearable app's <code>AndroidManifest.xml</code> file.
+The <code>rawPathResId</code> is the static variable name of the APK resource. For example,
 for <code>wearable_app.apk</code>, the static variable name is <code>wearable_app</code>.
 </p>
 </li>
@@ -124,7 +122,7 @@
 Add a <code>meta-data</code> tag to your handheld app's <code>&lt;application&gt;</code> tag to
 reference the <code>wearable_app_desc.xml</code> file.
 <pre>
-  &lt;meta-data android:name="com.google.android.wearable.beta.app" 
+  &lt;meta-data android:name="com.google.android.wearable.beta.app"
                  android:resource="&#64;xml/wearable_app_desc"/&gt;
 </pre>
 </li>
diff --git a/docs/html/training/wearables/apps/voice.jd b/docs/html/training/wearables/apps/voice.jd
index 4aa8031..6d49319 100644
--- a/docs/html/training/wearables/apps/voice.jd
+++ b/docs/html/training/wearables/apps/voice.jd
@@ -1,4 +1,7 @@
 page.title=Adding Voice Capabilities
+page.tags=wear
+helpoutsWidget=true
+
 @jd:body
 
 <div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/creating.jd b/docs/html/training/wearables/notifications/creating.jd
index 57ac36e..542664b 100644
--- a/docs/html/training/wearables/notifications/creating.jd
+++ b/docs/html/training/wearables/notifications/creating.jd
@@ -1,4 +1,6 @@
-page.title=Creating a Notification
+page.title=Creating a Notification for Wearables
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/index.jd b/docs/html/training/wearables/notifications/index.jd
index 2833dfa..6be945c 100644
--- a/docs/html/training/wearables/notifications/index.jd
+++ b/docs/html/training/wearables/notifications/index.jd
@@ -1,6 +1,8 @@
 page.title=Adding Wearable Features to Notifications
-page.tags="wear","notifications","wearables"
+page.tags=notifications, wear
 page.image=wear/images/01_notifications.png
+helpoutsWidget=true
+
 @jd:body
 
 <div id="tb-wrapper">
diff --git a/docs/html/training/wearables/notifications/pages.jd b/docs/html/training/wearables/notifications/pages.jd
index 6315037..41a3d7e 100644
--- a/docs/html/training/wearables/notifications/pages.jd
+++ b/docs/html/training/wearables/notifications/pages.jd
@@ -1,4 +1,6 @@
 page.title=Adding Pages to a Notification
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/stacks.jd b/docs/html/training/wearables/notifications/stacks.jd
index 9e70e1b..8056fc8 100644
--- a/docs/html/training/wearables/notifications/stacks.jd
+++ b/docs/html/training/wearables/notifications/stacks.jd
@@ -1,4 +1,6 @@
 page.title=Stacking Notifications
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/notifications/voice-input.jd b/docs/html/training/wearables/notifications/voice-input.jd
index 5a49343..73936f9 100644
--- a/docs/html/training/wearables/notifications/voice-input.jd
+++ b/docs/html/training/wearables/notifications/voice-input.jd
@@ -1,4 +1,6 @@
 page.title=Receiving Voice Input in a Notification
+page.tags=notifications
+helpoutsWidget=true
 
 @jd:body
 
diff --git a/docs/html/training/wearables/watch-faces/configuration.jd b/docs/html/training/wearables/watch-faces/configuration.jd
new file mode 100644
index 0000000..edc7eac
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/configuration.jd
@@ -0,0 +1,144 @@
+page.title=Providing Configuration Activities
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Intent">Specify an Intent for Configuration Activities</a></li>
+  <li><a href="#WearableActivity">Create a Wearable Configuration Activity</a></li>
+  <li><a href="#CompanionActivity">Create a Companion Configuration Activity</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>When users install a handheld app that contains a <a
+href="{@docRoot}training/wearables/apps/index.html">wearable app</a> with watch faces, these
+watch faces become available in the Android Wear companion app on the companion device and in
+the watch face picker on the wearable. Users can choose the active watch face for their wearable
+device by selecting it on the companion app or using the watch face picker on the wearable
+device.</p>
+
+<p>Some watch faces support configuration parameters to let users customize how the watch face
+looks and behaves. For example, some watch faces let users pick a custom background color, and
+watch faces that tell time for two different time zones can let users select which time zones
+they are interested in.</p>
+
+<p>Watch faces that support configuration parameters can let users customize a watch face using
+an activity in the wearable app, an activity on the handheld app, or both. Users can start the
+wearable configuration activity on the wearable device, and they can start the companion
+configuration activity from the Android Wear companion app.</p>
+
+<p>The digital watch face from the <em>WatchFace</em> sample in the Android SDK demonstrates how to
+implement handheld and wearable configuration activities and how to update a watch face in
+response to configuration changes. This sample is located in the
+<code>android-sdk/samples/android-21/wearable/WatchFace</code> directory.</p>
+
+
+
+<h2 id="Intent">Specify an Intent for Configuration Activities</h2>
+
+<p>If your watch face includes configuration activities, add the following metadata entries to
+the service declaration in the manifest file of the wearable app:</p>
+
+<pre>
+&lt;service
+    android:name=".DigitalWatchFaceService" ... />
+    &lt;!-- companion configuration activity -->
+    &lt;meta-data
+        android:name=
+           "com.google.android.wearable.watchface.companionConfigurationAction"
+        android:value=
+           "com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+    &lt;!-- wearable configuration activity -->
+    &lt;meta-data
+        android:name=
+           "com.google.android.wearable.watchface.wearableConfigurationAction"
+        android:value=
+           "com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+    ...
+&lt;/service>
+</pre>
+
+<p>Provide values for these entries that are preceded by the package name of your app.
+Configuration activities register intent filters for this intent, and the system fires this
+intent when users want to configure your watch face.</p>
+
+<p>If your watch face only includes a companion or a wearable configuration activity, you only
+need to include the corresponding metadata entry from the example above.</p>
+
+
+
+<h2 id="WearableActivity">Create a Wearable Configuration Activity</h2>
+
+<p>Wearable configuration activities provide a limited set of customization choices for a
+watch face, because complex menus are hard to navigate on smaller screens. Your wearable
+configuration activity should provide binary choices and just a few selections to customize
+the main aspects of your watch face.</p>
+
+<p>To create a wearable configuration activity, add a new activity to your wearable app module
+and declare the following intent filter in the manifest file of the wearable app:</p>
+
+<pre>
+&lt;activity
+    android:name=".DigitalWatchFaceWearableConfigActivity"
+    android:label="@string/digital_config_name">
+    &lt;intent-filter>
+        &lt;action android:name=
+            "com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+        &lt;category android:name=
+       "com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION" />
+        &lt;category android:name="android.intent.category.DEFAULT" />
+    &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>The name of the action in this intent filter must match the intent name you defined in
+<a href="#Intent">Specify an Intent for Configuration Activities</a>.</p>
+
+<p>In your configuration activity, build a simple UI that provides selections for users to
+customize your watch face. When users make a selection, use the <a
+href="{@docRoot}training/wearables/data-layer/index.html">Wearable Data Layer API</a> to
+communicate the configuration change to the watch face activity.</p>
+
+<p>For more details, see the <code>DigitalWatchFaceWearableConfigActivity</code> and
+<code>DigitalWatchFaceUtil</code> classes in the <em>WatchFace</em> sample.</p>
+
+
+
+<h2 id="CompanionActivity">Create a Companion Configuration Activity</h2>
+
+<p>Companion configuration activities give users access to the full set of configuration choices
+for a watch face, because it is easier to interact with complex menus on the larger screen of
+a handheld device. For example, a configuration activity on a handheld device enables you to
+present users with elaborate color pickers to select the background color of a watch face.</p>
+
+<p>To create a companion configuration activity, add a new activity to your handheld app module and
+declare the same intent filter for this activity as the one in <a href="#WearableActivity">Create
+a Wearable Configuration Activity</a>.</p>
+
+<p>In your configuration activity, build a UI that provides options to customize all the
+configurable elements of your watch face. When users make a selection, use the <a
+href="{@docRoot}training/wearables/data-layer/index.html">Wearable Data Layer API</a> to
+communicate the configuration change to the watch face activity.</p>
+
+<p>For more details, see the <code>DigitalWatchFaceCompanionConfigActivity</code> class in the
+<em>WatchFace</em> sample.</p>
+
+
+
+<h2 id="Listener">Create a Listener Service in the Wearable App</h2>
+
+<p>To receive updated configuration parameters from the configuration activities, create a
+service that implements the <code>WearableListenerService</code> interface from the <a
+href="{@docRoot}training/wearables/data-layer/index.html">Wearable Data Layer API</a> in your
+wearable app. Your watch face implementation can redraw the watch face when the configuration
+parameters change.</p>
+
+<p>For more details, see the <code>DigitalWatchFaceConfigListenerService</code> and
+<code>DigitalWatchFaceService</code> classes in the <em>WatchFace</em> sample.</p>
diff --git a/docs/html/training/wearables/watch-faces/designing.jd b/docs/html/training/wearables/watch-faces/designing.jd
new file mode 100644
index 0000000..1033fed
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/designing.jd
@@ -0,0 +1,116 @@
+page.title=Designing Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#DesignGuidelines">Conform to the Design Guidelines</a></li>
+  <li><a href="#ImplementationStrategy">Create an Implementation Strategy</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<!-- design guide box -->
+<a class="notice-designers wide" href="{@docRoot}design/wear/watchfaces.html">
+  <div>
+    <h3>Design Guide</h3>
+    <p>Watch Faces</p>
+  </div>
+</a>
+
+<p>Similar to the process of designing a traditional watch face, creating one for
+Android Wear is an exercise in visualizing time clearly. Android Wear devices
+provide advanced capabilities for watch faces that you can leverage in your designs, such as
+vibrant colors, dynamic backgrounds, animations, and data integration. However, there are
+also many design considerations that you must take into account.</p>
+
+<p>This lesson provides a summary of the design considerations for watch faces and general
+guidelines to get started implementing a design. For more information, read the <a
+href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a> design guide.</p>
+
+
+
+<h2 id="DesignGuidelines">Conform to the Design Guidelines</h2>
+
+<p>As you plan the look of your watch face and what kind of information it should present
+to users, consider these design guidelines:</p>
+
+<div style="float:right;margin-top:-5px;margin-left:20px">
+  <img src="{@docRoot}training/wearables/watch-faces/images/Render_Next.png"
+       width="200" height="195" alt="" style="margin-right:5px"/><br>
+  <img src="{@docRoot}training/wearables/watch-faces/images/Render_Interactive.png"
+       width="200" height="195" alt="" style="margin-right:5px"/>
+  <p class="img-caption" style="margin-top:0px;margin-left:10px">
+  <strong>Figure 1.</strong> Example watch faces.</p>
+</div>
+
+<dl>
+<dt><em>Plan for square and round devices</em></dt>
+<dd>Your design should work for both square and round Android Wear devices, including devices with
+<a href="{@docRoot}training/wearables/ui/layouts.html#same-layout">insets on the bottom of the
+screen</a>.</dd>
+
+<dt><em>Support all display modes</em></dt>
+<dd>Your watch face should support ambient mode with limited color and interactive mode with
+full color and animations.</dd>
+
+<dt><em>Optimize for special screen technologies</em></dt>
+<dd>In ambient mode, your watch face should keep most pixels black. Depending on the screen
+technology, you may need to avoid large blocks of white pixels, use only black and white, and
+disable anti-aliasing.</dd>
+
+<dt><em>Accomodate system UI elements</em></dt>
+<dd>Your design should ensure that system indicators remain visible and that users can still
+read the time when notification cards appear on the screen.</dd>
+
+<dt><em>Integrate data</em></dt>
+<dd>Your watch face can leverage sensors and cellular connectivity on the companion mobile
+device to show user data relevant to the context, such as the weather for the day or their next
+calendar event.</dd>
+
+<dt><em>Provide configuration options</em></dt>
+<dd>You can let users configure some aspects of your design (like colors and sizes) on the
+wearable or on the Android Wear companion app.</dd>
+</dl>
+
+<p>For more information about designing watch faces for Android Wear, see the <a
+href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a> design guide.</p>
+
+
+
+<h2 id="ImplementationStrategy">Create an Implementation Strategy</h2>
+
+<p>After you finalize the design for your watch face, you need to determine how to obtain any
+necessary data and draw the watch face on the wearable device. Most implementations
+consist of the following components:</p>
+
+<ul>
+<li>One or more background images</li>
+<li>Application code to retrieve the required data</li>
+<li>Application code to draw text and shapes over the background images</li>
+</ul>
+
+<p>You typically use one background image in interactive mode and a different background image
+in ambient mode. The background in ambient mode is often completely black. Background images for
+Android Wear devices with a screen density of hdpi should be 320 by 320 pixels in size to fit
+both square and round devices. The corners of the background image are not visible on round
+devices. In your code, you can detect the size of the device screen and scale down the background
+image if the device has a lower resolution than your image. To improve performance, you should
+scale the background image only once and store the resulting bitmap.</p>
+
+<p>You should run the application code to retrieve contextual data only as often as required
+and store the results to reuse the data every time you draw the watch face. For example, you
+don't need to fetch weather updates every minute.</p>
+
+<p>To increase battery life, the application code that draws your watch face in ambient mode
+should be relatively simple. You usually draw outlines of shapes using a limited set of colors
+in this mode. In interactive mode, you can use full color, complex shapes, gradients, and
+animations to draw your watch face.</p>
+
+<p>The remaining lessons in this class show you how to implement watch faces in detail.</p>
diff --git a/docs/html/training/wearables/watch-faces/drawing.jd b/docs/html/training/wearables/watch-faces/drawing.jd
new file mode 100644
index 0000000..9afdd80
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/drawing.jd
@@ -0,0 +1,509 @@
+page.title=Drawing Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Initialize">Initialize Your Watch Face</a></li>
+  <li><a href="#SystemUI">Configure the System UI</a></li>
+  <li><a href="#Screen">Obtain Information About the Device Screen</a></li>
+  <li><a href="#Modes">Respond to Changes Between Modes</a></li>
+  <li><a href="#Drawing">Draw Your Watch Face</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>After you have configured your project and added a class that implements the watch
+face service, you can start writing code to initialize and draw your custom watch face.</p>
+
+<p>This lesson explains how the system invokes the methods in the
+watch face service using examples from the <em>WatchFace</em> sample
+included in the Android SDK. This sample is located in the
+<code>android-sdk/samples/android-21/wearable/WatchFace</code> directory. Many aspects of the
+service implementations described here (such as initialization and detecting device features)
+apply to any watch face, so you can reuse some of the code in your own watch faces.</p>
+
+
+<img src="{@docRoot}training/wearables/watch-faces/images/preview_analog.png"
+     width="180" height="180" alt="" style="margin-top:12px"/>
+<img src="{@docRoot}training/wearables/watch-faces/images/preview_digital.png"
+     width="180" height="180" alt="" style="margin-left:25px;margin-top:12px"/>
+<p class="img-caption">
+<strong>Figure 1.</strong> The analog and digital watch faces in
+the <em>WatchFace</em> sample.</p>
+
+
+<h2 id="Initialize">Initialize Your Watch Face</h2>
+
+<p>When the system loads your service, you should allocate and initialize most of the resources
+that your watch face needs, including loading bitmap resources, creating timer objects to run
+custom animations, configuring paint styles, and performing other computations. You can usually
+perform these operations only once and reuse their results. This practice improves the performance
+of your watch face and makes it easier to maintain your code.</p>
+
+<p>To initialize your watch face, follow these steps:</p>
+
+<ol>
+<li>Declare variables for a custom timer, graphic objects, and other elements.</li>
+<li>Initialize the watch face elements in the <code>Engine.onCreate()</code> method.</li>
+<li>Initialize the custom timer in the <code>Engine.onVisibilityChanged()</code> method.</li>
+</ol>
+
+<p>The following sections describe these steps in detail.</p>
+
+<h3 id="Variables">Declare variables</h3>
+
+<p>The resources that you intialize when the system loads your service need to be accessible
+at different points throughout your implementation, so you can reuse them. You achieve this
+by declaring member variables for these resources in your <code>WatchFaceService.Engine</code>
+implementation.</p>
+
+<p>Declare variables for the following elements:</p>
+
+<dl>
+<dt><em>Graphic objects</em></dt>
+<dd>Most watch faces contain at least one bitmap image used as the background of the watch face,
+as described in
+<a href="{@docRoot}training/wearables/watch-faces/designing.html#ImplementationStrategy">Create an
+Implementation Strategy</a>. You can use additional bitmap images that represent clock hands or
+other design elements of your watch face.</dd>
+<dt><em>Periodic timer</em></dt>
+<dd>The system notifies the watch face once a minute when the time changes, but some watch faces
+run animations at custom time intervals. In these cases, you need to provide a custom timer that
+ticks with the frequency required to update your watch face.</dd>
+<dt><em>Time zone change receiver</em></dt>
+<dd>Users can adjust their time zone when they travel, and the system broadcasts this event.
+Your service implementation must register a broadcast receiver that is notified when the time
+zone changes and update the time accordingly.</dd>
+</dl>
+
+<p>The <code>AnalogWatchFaceService.Engine</code> class in the <em>WatchFace</em> sample defines
+these variables as shown in the snippet below. The custom timer is implemented as a
+{@link android.os.Handler} instance that sends and processes delayed messages using the thread's
+message queue. For this particular watch face, the custom timer ticks once every second. When the
+timer ticks, the handler calls the <code>invalidate()</code> method and the system then calls
+the <code>onDraw()</code> method to redraw the watch face.</p>
+
+<pre>
+private class Engine extends CanvasWatchFaceService.Engine {
+    static final int MSG_UPDATE_TIME = 0;
+
+    /* a time object */
+    Time mTime;
+
+    /* device features */
+    boolean mLowBitAmbient;
+
+    /* graphic objects */
+    Bitmap mBackgroundBitmap;
+    Bitmap mBackgroundScaledBitmap;
+    Paint mHourPaint;
+    Paint mMinutePaint;
+    ...
+
+    /* handler to update the time once a second in interactive mode */
+    final Handler mUpdateTimeHandler = new Handler() {
+        &#64;Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_UPDATE_TIME:
+                    invalidate();
+                    if (shouldTimerBeRunning()) {
+                        long timeMs = System.currentTimeMillis();
+                        long delayMs = INTERACTIVE_UPDATE_RATE_MS
+                                - (timeMs % INTERACTIVE_UPDATE_RATE_MS);
+                        mUpdateTimeHandler
+                            .sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
+                    }
+                    break;
+            }
+        }
+    };
+
+    /* receiver to update the time zone */
+    final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
+        &#64;Override
+        public void onReceive(Context context, Intent intent) {
+            mTime.clear(intent.getStringExtra("time-zone"));
+            mTime.setToNow();
+        }
+    };
+
+    /* service methods (see other sections) */
+    ...
+}
+</pre>
+
+<h3 id="InitializeElements">Initialize watch face elements</h3>
+
+<p>After you have declared member variables for bitmap resources, paint styles, and other
+elements that you reuse every time your redraw your watch face, initialize them when the system
+loads your service. Initializing these elements only once and reusing them improves performance
+and battery life.</p>
+
+<p>In the <code>Engine.onCreate()</code> method, initialize the following elements:</p>
+
+<ul>
+<li>Load the background image.</li>
+<li>Create styles and colors to draw graphic objects.</li>
+<li>Allocate an object to hold the time.</li>
+<li>Configure the system UI.</li>
+</ul>
+
+<p>The <code>Engine.onCreate()</code> method in the <code>AnalogWatchFaceService</code> class
+initializes these elements as follows:</p>
+
+<pre>
+&#64;Override
+public void onCreate(SurfaceHolder holder) {
+    super.onCreate(holder);
+
+    /* configure the system UI (see next section) */
+    ...
+
+    /* load the background image */
+    Resources resources = AnalogWatchFaceService.this.getResources();
+    Drawable backgroundDrawable = resources.getDrawable(R.drawable.bg);
+    mBackgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
+
+    /* create graphic styles */
+    mHourPaint = new Paint();
+    mHourPaint.setARGB(255, 200, 200, 200);
+    mHourPaint.setStrokeWidth(5.0f);
+    mHourPaint.setAntiAlias(true);
+    mHourPaint.setStrokeCap(Paint.Cap.ROUND);
+    ...
+
+    /* allocate an object to hold the time */
+    mTime = new Time();
+}
+</pre>
+
+<p>The background bitmap is loaded only once when the system initializes the watch face. The
+graphic styles are instances of the {@link android.graphics.Paint} class. You later use these
+styles to draw the elements of your watch face inside the <code>Engine.onDraw()</code> method,
+as described in <a href="#Drawing">Drawing Your Watch Face</a>.</p>
+
+<h3 id="Timer">Initialize the custom timer</h3>
+
+<p>As a watch face developer, you can decide how often you want to update your watch face by
+providing a custom timer that ticks with the required frequency while the device is in
+interactive mode. This enables you to create custom animations and other visual effects. In
+ambient mode, you should disable the timer to let the CPU sleep and update the watch face
+only when the time changes. For more information, see
+<a href="{@docRoot}training/wearables/watch-faces/performance.html">Optimizing Performance and
+Battery Life</a>.</p>
+
+<p>An example timer definition from the <code>AnalogWatchFaceService</code> class that ticks once
+every second is shown in <a href="#Variables">Declare variables</a>. In the
+<code>Engine.onVisibilityChanged()</code> method, start the custom timer if these two
+conditions apply:</p>
+
+<ul>
+<li>The watch face is visible.</li>
+<li>The device is in interactive mode.</li>
+</ul>
+
+<p>The timer should not run under any other conditions, since this watch face does not
+draw the second hand in ambient mode to conserve power. The <code>AnalogWatchFaceService</code>
+class schedules the next timer tick if required as follows:</p>
+
+<pre>
+private void updateTimer() {
+    mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
+    if (shouldTimerBeRunning()) {
+        mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
+    }
+}
+
+private boolean shouldTimerBeRunning() {
+    return isVisible() &amp;&amp; !isInAmbientMode();
+}
+</pre>
+
+<p>This custom timer ticks once every second, as described in <a href="#Variables">Declare
+variables</a>.</p>
+
+<p>In the <code>Engine.onVisibilityChanged()</code> method, start the timer if required and
+and register the receiver for time zone changes as follows:</p>
+
+<pre>
+&#64;Override
+public void onVisibilityChanged(boolean visible) {
+    super.onVisibilityChanged(visible);
+
+    if (visible) {
+        registerReceiver();
+
+        // Update time zone in case it changed while we weren't visible.
+        mTime.clear(TimeZone.getDefault().getID());
+        mTime.setToNow();
+    } else {
+        unregisterReceiver();
+    }
+
+    // Whether the timer should be running depends on whether we're visible and
+    // whether we're in ambient mode), so we may need to start or stop the timer
+    updateTimer();
+}
+</pre>
+
+<p>When the watch face is visible, the <code>onVisibilityChanged()</code> method registers
+the receiver for time zone changes and starts the custom timer if the device is in interactive
+mode. When the watch face is not visible, this method stops the custom timer and unregisters
+the receiver for time zone changes. The <code>registerReceiver()</code> and
+<code>unregisterReceiver()</code> methods are implemented as follows:</p>
+
+<pre>
+private void registerReceiver() {
+    if (mRegisteredTimeZoneReceiver) {
+        return;
+    }
+    mRegisteredTimeZoneReceiver = true;
+    IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
+    AnalogWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
+}
+
+private void unregisterReceiver() {
+    if (!mRegisteredTimeZoneReceiver) {
+        return;
+    }
+    mRegisteredTimeZoneReceiver = false;
+    AnalogWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
+}
+</pre>
+
+
+
+<h3 id="TimeTick">Invalidate the canvas when the time changes</h3>
+
+<p>The system calls the <code>Engine.onTimeTick()</code> method every minute. In ambient mode,
+it is usually sufficient to update your watch face once per minute. To update your watch face
+more often while in interactive mode, you provide a custom timer as described in
+<a href="#Timer">Initialize the custom timer</a>.</p>
+
+<p>Most watch face implementations just invalidate the canvas to redraw the watch face when
+the time changes:</p>
+
+<pre>
+&#64;Override
+public void onTimeTick() {
+    super.onTimeTick();
+
+    invalidate();
+}
+</pre>
+
+
+
+<h2 id="SystemUI">Configure the System UI</h2>
+
+<p>Watch faces should not interfere with system UI elements, as described in
+<a href="{@docRoot}design/wear/watchfaces.html#SystemUI">Accommodate System UI Elements</a>.
+If your watch face has a light background or shows information near the bottom of the screen,
+you may have to configure the size of notification cards or enable background protection.</p>
+
+<p>Android Wear enables you to configure the following aspects of the system UI when your watch
+face is active:</p>
+
+<ul>
+<li>Specify how far the first notification card peeks into the screen.</li>
+<li>Specify whether the system draws the time over your watch face.</li>
+<li>Show or hide cards when in ambient mode.</li>
+<li>Protect the system indicators with a solid background around them.</li>
+<li>Specify the positioning of the system indicators.</li>
+</ul>
+
+<p>To configure these aspects of the system UI, create a <code>WatchFaceStyle</code> instance
+and pass it to the <code>Engine.setWatchFaceStyle()</code> method.</p>
+
+<p>The <code>AnalogWatchFaceService</code> class configures the system UI as follows:</p>
+
+<pre>
+&#64;Override
+public void onCreate(SurfaceHolder holder) {
+    super.onCreate(holder);
+
+    /* configure the system UI */
+    setWatchFaceStyle(new WatchFaceStyle.Builder(AnalogWatchFaceService.this)
+            .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
+            .setBackgroundVisibility(WatchFaceStyle
+                                    .BACKGROUND_VISIBILITY_INTERRUPTIVE)
+            .setShowSystemUiTime(false)
+            .build());
+    ...
+}
+</pre>
+
+<p>The code snippet above configures peeking cards to be a single line tall, the background
+of a peeking card to show only briefly and only for interruptive notifications, and the system
+time not to be shown (since this watch face draws its own time representation).</p>
+
+<p>You can configure the style of the system UI at any point in your watch face implementation.
+For example, if the user selects a white background, you can add background protection for the
+system indicators.</p>
+
+<p>For more details about configuring the system UI, see the
+<a href="{@docRoot}shareables/training/wearable-support-docs.zip">API reference</a> for the
+<code>WatchFaceStyle</code> class.</p>
+
+
+
+<h2 id="Screen">Obtain Information About the Device Screen</h2>
+
+<p>The system calls the <code>Engine.onPropertiesChanged()</code> method when it determines
+the properties of the device screen, such as whether the device uses low-bit ambient mode and
+whether the screen requires burn-in protection.</p>
+
+<p>The following code snippet shows how to obtain these properties:</p>
+
+<pre>
+&#64;Override
+public void onPropertiesChanged(Bundle properties) {
+    super.onPropertiesChanged(properties);
+    mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
+    mBurnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION,
+            false);
+}
+</pre>
+
+<p>You should take these device properties into account when drawing your watch face:</p>
+
+<ul>
+<li>For devices that use low-bit ambient mode, the screen supports fewer bits for each color
+in ambient mode, so you should disable anti-aliasing.</li>
+<li>For devices that require burn-in protection, avoid using large blocks of white pixels in
+ambient mode and do not place content within 10 pixels of the edge of the screen, since the
+system shifts the content periodically to avoid pixel burn-in.</li>
+</ul>
+
+<p>For more information about low-bit ambient mode and burn-in protection, see
+<a href="{@docRoot}design/wear/watchfaces.html#SpecialScreens">Optimize for Special
+Screens</a>.</p>
+
+
+<h2 id="Modes">Respond to Changes Between Modes</h2>
+
+<p>When the device switches between ambient and interactive modes, the system calls the
+<code>Engine.onAmbientModeChanged()</code> method. Your service implementation should make
+any necessary adjustments to switch between modes and then call the <code>invalidate()</code>
+method for the system to redraw the watch face.</p>
+
+<p>The following snippet shows how this method is implemented in the
+<code>AnalogWatchFaceService</code> class inside the <em>WatchFace</em> sample:</p>
+
+<pre>
+&#64;Override
+public void onAmbientModeChanged(boolean inAmbientMode) {
+
+    boolean wasInAmbientMode = isInAmbientMode();
+    super.onAmbientModeChanged(inAmbientMode);
+
+    if (inAmbientMode != wasInAmbientMode) {
+        if (mLowBitAmbient) {
+            boolean antiAlias = !inAmbientMode;
+            mHourPaint.setAntiAlias(antiAlias);
+            mMinutePaint.setAntiAlias(antiAlias);
+            mSecondPaint.setAntiAlias(antiAlias);
+            mTickPaint.setAntiAlias(antiAlias);
+        }
+        invalidate();
+        updateTimer();
+    }
+}
+</pre>
+
+<p>This example makes adjustments to some graphic styles and invalidates the canvas so the
+system can redraw the watch face.</p>
+
+
+
+<h2 id="Drawing">Draw Your Watch Face</h2>
+
+<p>To draw a custom watch face, the system calls the <code>Engine.onDraw()</code> method with a
+{@link android.graphics.Canvas} instance and the bounds in which you should draw your watch face.
+The bounds account for any inset areas, such as the "chin" on the bottom of some round devices.
+You can use this canvas to draw your watch face directly as follows:</p>
+
+<ol>
+<li>If this is the first invocation of the <code>onDraw()</code> method, scale your background
+to fit.</li>
+<li>Check whether the device is in ambient mode or interactive mode.</li>
+<li>Perform any required graphic computations.</li>
+<li>Draw your background bitmap on the canvas.</li>
+<li>Use the methods in the {@link android.graphics.Canvas} class to draw your watch face.</li>
+</ol>
+
+<p>The <code>AnalogWatchFaceService</code> class in the <em>WatchFace</em> sample follows these
+steps to implement the <code>onDraw()</code> method as follows:</p>
+
+<pre>
+&#64;Override
+public void onDraw(Canvas canvas, Rect bounds) {
+    // Update the time
+    mTime.setToNow();
+
+    int width = bounds.width();
+    int height = bounds.height();
+
+    // Draw the background, scaled to fit.
+    if (mBackgroundScaledBitmap == null
+        || mBackgroundScaledBitmap.getWidth() != width
+        || mBackgroundScaledBitmap.getHeight() != height) {
+        mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
+                                         width, height, true /* filter */);
+    }
+    canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null);
+
+    // Find the center. Ignore the window insets so that, on round watches
+    // with a "chin", the watch face is centered on the entire screen, not
+    // just the usable portion.
+    float centerX = width / 2f;
+    float centerY = height / 2f;
+
+    // Compute rotations and lengths for the clock hands.
+    float secRot = mTime.second / 30f * (float) Math.PI;
+    int minutes = mTime.minute;
+    float minRot = minutes / 30f * (float) Math.PI;
+    float hrRot = ((mTime.hour + (minutes / 60f)) / 6f ) * (float) Math.PI;
+
+    float secLength = centerX - 20;
+    float minLength = centerX - 40;
+    float hrLength = centerX - 80;
+
+    // Only draw the second hand in interactive mode.
+    if (!mAmbient) {
+        float secX = (float) Math.sin(secRot) * secLength;
+        float secY = (float) -Math.cos(secRot) * secLength;
+        canvas.drawLine(centerX, centerY, centerX + secX, centerY +
+                        secY, mSecondPaint);
+    }
+
+    // Draw the minute and hour hands.
+    float minX = (float) Math.sin(minRot) * minLength;
+    float minY = (float) -Math.cos(minRot) * minLength;
+    canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY,
+                    mMinutePaint);
+    float hrX = (float) Math.sin(hrRot) * hrLength;
+    float hrY = (float) -Math.cos(hrRot) * hrLength;
+    canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY,
+                    mHourPaint);
+}
+</pre>
+
+<p>This method computes the required positions for the clock hands based on the current time
+and draws them on top of the background bitmap using the graphic styles initialized in the
+<code>onCreate()</code> method. The second hand is only drawn in interactive mode, not in
+ambient mode.</p>
+
+<p>For more information about drawing on a Canvas instance, see <a
+href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and Drawables</a>.</p>
+
+<p>The <em>WatchFace</em> sample in the Android SDK includes additional watch faces that you
+can refer to as examples of how to implement the <code>onDraw()</code> method.</p>
diff --git a/docs/html/training/wearables/watch-faces/images/AnalogNoCard.png b/docs/html/training/wearables/watch-faces/images/AnalogNoCard.png
new file mode 100644
index 0000000..a6b5d4f
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/AnalogNoCard.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/AnalogWithCard.png b/docs/html/training/wearables/watch-faces/images/AnalogWithCard.png
new file mode 100644
index 0000000..242d3fe
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/AnalogWithCard.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/BitmapFilterDisabled.png b/docs/html/training/wearables/watch-faces/images/BitmapFilterDisabled.png
new file mode 100644
index 0000000..3291137
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/BitmapFilterDisabled.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/BitmapFilterEnabled.png b/docs/html/training/wearables/watch-faces/images/BitmapFilterEnabled.png
new file mode 100644
index 0000000..6492318
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/BitmapFilterEnabled.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/ClockHandCropped.png b/docs/html/training/wearables/watch-faces/images/ClockHandCropped.png
new file mode 100644
index 0000000..69c746b
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/ClockHandCropped.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/ClockHandFull.png b/docs/html/training/wearables/watch-faces/images/ClockHandFull.png
new file mode 100644
index 0000000..2d08920
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/ClockHandFull.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/Indicators_Cropped.png b/docs/html/training/wearables/watch-faces/images/Indicators_Cropped.png
new file mode 100644
index 0000000..9449c02
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/Indicators_Cropped.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/Render_Episode.png b/docs/html/training/wearables/watch-faces/images/Render_Episode.png
new file mode 100644
index 0000000..2d545bb
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/Render_Episode.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/Render_Interactive.png b/docs/html/training/wearables/watch-faces/images/Render_Interactive.png
new file mode 100644
index 0000000..a1e260b
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/Render_Interactive.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/Render_Next.png b/docs/html/training/wearables/watch-faces/images/Render_Next.png
new file mode 100644
index 0000000..e080943
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/Render_Next.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/Render_Saturn.png b/docs/html/training/wearables/watch-faces/images/Render_Saturn.png
new file mode 100644
index 0000000..500018c
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/Render_Saturn.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/preview_analog.png b/docs/html/training/wearables/watch-faces/images/preview_analog.png
new file mode 100644
index 0000000..fa71546
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/preview_analog.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/preview_calendar.png b/docs/html/training/wearables/watch-faces/images/preview_calendar.png
new file mode 100644
index 0000000..928aa1f
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/preview_calendar.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/images/preview_digital.png b/docs/html/training/wearables/watch-faces/images/preview_digital.png
new file mode 100644
index 0000000..4853a64
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/images/preview_digital.png
Binary files differ
diff --git a/docs/html/training/wearables/watch-faces/index.jd b/docs/html/training/wearables/watch-faces/index.jd
new file mode 100644
index 0000000..c7affd1
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/index.jd
@@ -0,0 +1,70 @@
+page.title=Creating Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+  <h2>Dependencies and Prerequisites</h2>
+  <ul>
+    <li>Android Studio 1.0.0 or later and Gradle 1.0 or later</li>
+    <li>Android 4.3 (API level 18) or higher on the handheld device</li>
+    <li>Android 5.0 (API level 21) or higher on the wearable device</li>
+  </ul>
+</div>
+</div>
+
+<!-- design guide box -->
+<a class="notice-designers wide" href="{@docRoot}design/wear/watchfaces.html">
+  <div>
+    <h3>Design Guide</h3>
+    <p>Watch Faces</p>
+  </div>
+</a>
+
+<p>Watch faces in Android Wear leverage a dynamic digital canvas to tell time using colors,
+animations, and relevant contextual information. The <a
+href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app">Android
+Wear companion app</a> provides watch faces with different styles and shapes. When
+users select one of the available watch faces on the wearable or on the companion app, the
+wearable device previews the watch face and lets the user set configuration options.</p>
+
+<p>Android Wear enables you to create custom watch faces for Wear devices. When users install a
+handheld app that contains a <a href="{@docRoot}training/wearables/apps/index.html">wearable
+app</a> with watch faces, they become available in the Android Wear companion app
+on the handheld device and in the watch face picker on the wearable device.</p>
+
+<p>This class teaches you to implement custom watch faces and to package them inside a wearable
+app. This class also covers design considerations and implementation tips to ensure that your
+designs integrate with system UI elements and are power-efficient.</p>
+
+<p class="note"><strong>Note:</strong> We recommend using <a
+href="{@docRoot}sdk/index.html">Android Studio</a> for Android Wear development as
+it provides project setup, library inclusion, and packaging conveniences that aren't available
+in the Eclipse Android Developer Tools. This training assumes you are using Android Studio.</p>
+
+
+<h2>Lessons</h2>
+
+<dl>
+<dt><a href="{@docRoot}training/wearables/watch-faces/designing.html">
+Designing Watch Faces</a></dt>
+<dd>Learn how to design a watch face that works on any Android Wear device.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/service.html">
+Building a Watch Face Service</a></dt>
+<dd>Learn how to respond to important events during the lifecycle of your watch face.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/drawing.html">
+Drawing Watch Faces</a></dt>
+<dd>Learn how to draw your watch face on a Wear device screen.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/information.html">
+Showing Information in Watch Faces</a></dt>
+<dd>Learn how to incorporate contextual information into your watch face.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/configuration.html">
+Providing Configuration Activities</a></dt>
+<dd>Learn how to create watch faces with configurable parameters.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/issues.html">
+Addressing Common Issues</a></dt>
+<dd>Learn how to fix common problems when developing a watch face.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/performance.html">
+Optimizing Performance and Battery Life</a></dt>
+<dd>Learn how to improve the frame rate of your animations and how to save power.</dd>
+</dl>
diff --git a/docs/html/training/wearables/watch-faces/information.jd b/docs/html/training/wearables/watch-faces/information.jd
new file mode 100644
index 0000000..41319a1
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/information.jd
@@ -0,0 +1,213 @@
+page.title=Showing Information in Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Experience">Create a Compelling Experience</a></li>
+  <li><a href="#AddData">Add Data to Your Watch Face</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>In addition to telling time, Android Wear devices provide users with contextually relevant
+information in the form of cards, notifications, and other wearable apps. Creating a custom
+watch face not only gives you the opportunity to tell time in visually compelling ways, but
+also to show users relevant information whenever they glance at their device.</p>
+
+<p>Like any other wearable app, your watch face can communicate with apps running on the handheld
+device using the <a href="{@docRoot}training/wearables/data-layer/index.html">Wearable Data Layer
+API</a>. In some cases, you need to create an activity in the handheld app module of your project
+that retrieves data from the Internet or from the user's profile and then shares it with your
+watch face.</p>
+
+<img src="{@docRoot}training/wearables/watch-faces/images/Render_Saturn.png"
+     width="200" height="196" alt="" style="margin-top:12px;margin-left:-20px"/>
+<img src="{@docRoot}training/wearables/watch-faces/images/Render_Episode.png"
+     width="200" height="196" alt="" style="margin-top:12px;margin-left:-25px"/>
+<p class="img-caption">
+<strong>Figure 1.</strong> Examples of watch faces with integrated data.</p>
+
+
+<h2 id="Experience">Create a Compelling Experience</h2>
+
+<p>Before you design and implement a contextually-aware watch face, answer the following
+questions:</p>
+
+<ul>
+<li>What kind of data do you want to incorporate?</li>
+<li>Where can you obtain this data?</li>
+<li>How often does the data change significantly?</li>
+<li>How can you present the data such that users understand it at a glance?</li>
+</ul>
+
+<p>Android Wear devices are usually paired with a companion device that has a GPS sensor and
+cellular connectivity, so you have endless possibilities to integrate different kinds of data
+in your watch face, such as location, calendar events, social media trends, picture feeds, stock
+market quotes, news events, sports scores, and so on. However, not all kinds of data are
+appropriate for a watch face, so you should consider what kinds of data are most relevant to
+your users throughout the day. Your watch face should also gracefully handle the case where the
+wearable is not paired with a companion device or when an Internet connection is not available.</p>
+
+<p>The active watch face on an Android Wear device is an app that runs continuously, so you
+must retrieve data in a battery-efficient manner. For example, you can obtain the current
+weather every ten minutes and store the results locally, instead of requesting an update every
+minute. You can also refresh contextual data when the device switches from ambient to interactive
+mode, since the user is more likely to glance at the watch when this transition occurs.</p>
+
+<p>You should summarize contextual information on your watch face, since there is limited
+space available on the screen and users just glance at their watch for a second or two at a
+time. Sometimes the best way to convey contextual information is to react to it using graphics
+and colors. For example, a watch face could change its background image depending on the current
+weather.</p>
+
+
+
+<h2 id="AddData">Add Data to Your Watch Face</h2>
+
+<div style="float:right;margin-left:20px">
+<img src="{@docRoot}training/wearables/watch-faces/images/preview_calendar.png"
+     width="180" height="180" alt="" style="margin-left:10px;margin-top:10px"/>
+<p class="img-caption"><strong>Figure 2.</strong> The calendar watch face.</p>
+</div>
+
+<p>The <em>WatchFace</em> sample in the Android SDK demonstrates how to obtain calendar data
+from the user’s profile in the <code>CalendarWatchFaceService</code> class and shows how many
+meetings there are in the following twenty-four hours. This sample is located in the
+<code>android-sdk/samples/android-21/wearable/WatchFace</code> directory.</p>
+
+<p>To implement a watch face that incorporates contextual data, follow these steps:</p>
+
+<ol>
+<li>Provide a task that retrieves the data.</li>
+<li>Create a custom timer to invoke your task periodically, or notify your watch face service
+    when external data changes.</li>
+<li>Redraw your watch face with the updated data.</li>
+</ol>
+
+<p>The following sections describe these steps in detail.</p>
+
+<h3 id="Task">Provide a task to retrieve data</h3>
+
+<p>Create a class inside your <code>CanvasWatchFaceService.Engine</code> implementation that
+extends {@link android.os.AsyncTask} and add the code to retrieve the data you’re interested
+in.</p>
+
+<p>The <code>CalendarWatchFaceService</code> class obtains the number of meetings in the next
+day as follows:</p>
+
+<pre>
+/* Asynchronous task to load the meetings from the content provider and
+ * report the number of meetings back using onMeetingsLoaded() */
+private class LoadMeetingsTask extends AsyncTask&lt;Void, Void, Integer> {
+    &#64;Override
+    protected Integer doInBackground(Void... voids) {
+        long begin = System.currentTimeMillis();
+        Uri.Builder builder =
+                WearableCalendarContract.Instances.CONTENT_URI.buildUpon();
+        ContentUris.appendId(builder, begin);
+        ContentUris.appendId(builder, begin + DateUtils.DAY_IN_MILLIS);
+        final Cursor cursor = getContentResolver() .query(builder.build(),
+                null, null, null, null);
+        int numMeetings = cursor.getCount();
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "Num meetings: " + numMeetings);
+        }
+        return numMeetings;
+    }
+
+    &#64;Override
+    protected void onPostExecute(Integer result) {
+        /* get the number of meetings and set the next timer tick */
+        onMeetingsLoaded(result);
+    }
+}
+</pre>
+
+<p>The <code>WearableCalendarContract</code> class from the Wearable Support Library provides
+direct access to the user's calendar events from the companion device.</p>
+
+<p>When the task finishes retrieving data, your code invokes a callback method. The following
+sections describe how to implement the callback method in detail.</p>
+
+<p>For more information about obtaining data from the calendar, see the <a
+href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a> API
+guide.</p>
+
+<h3 id="Timer">Create a custom timer</h3>
+
+<p>You can implement a custom timer that ticks periodically to update your data.
+The <code>CalendarWatchFaceService</code> class uses a {@link android.os.Handler} instance
+that sends and processes delayed messages using the thread's message queue:</p>
+
+<pre>
+private class Engine extends CanvasWatchFaceService.Engine {
+    ...
+    int mNumMeetings;
+    private AsyncTask&lt;Void, Void, Integer> mLoadMeetingsTask;
+
+    /* Handler to load the meetings once a minute in interactive mode. */
+    final Handler mLoadMeetingsHandler = new Handler() {
+        &#64;Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_LOAD_MEETINGS:
+                    cancelLoadMeetingTask();
+                    mLoadMeetingsTask = new LoadMeetingsTask();
+                    mLoadMeetingsTask.execute();
+                    break;
+            }
+        }
+    };
+    ...
+}
+</pre>
+
+<p>This method initializes the timer when the watch face becomes visible:</p>
+
+<pre>
+&#64;Override
+public void onVisibilityChanged(boolean visible) {
+    super.onVisibilityChanged(visible);
+    if (visible) {
+        mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
+    } else {
+        mLoadMeetingsHandler.removeMessages(MSG_LOAD_MEETINGS);
+        cancelLoadMeetingTask();
+    }
+}
+</pre>
+
+<p>The next timer tick is set in the <code>onMeetingsLoaded()</code> method, as shown in the next
+section.</p>
+
+<h3 id="Redraw">Redraw your watch face with the updated data</h3>
+
+<p>When the task that retrieves your data finishes, call the <code>invalidate()</code> method
+so the system redraws your watch face. Store your data inside member variables of the
+<code>Engine</code> class so you can access it inside the <code>onDraw()</code> method.</p>
+
+<p>The <code>CalendarWatchFaceService</code> class provides a callback method for the task to
+invoke when it finishes retrieving calendar data:</p>
+
+<pre>
+private void onMeetingsLoaded(Integer result) {
+    if (result != null) {
+        mNumMeetings = result;
+        invalidate();
+    }
+    if (isVisible()) {
+        mLoadMeetingsHandler.sendEmptyMessageDelayed(
+                MSG_LOAD_MEETINGS, LOAD_MEETINGS_DELAY_MS);
+    }
+}
+</pre>
+
+<p>The callback method stores the result in a member variable, invalidates the view, and
+schedules the next timer tick to run the task again.</p>
diff --git a/docs/html/training/wearables/watch-faces/issues.jd b/docs/html/training/wearables/watch-faces/issues.jd
new file mode 100644
index 0000000..47c5e8c
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/issues.jd
@@ -0,0 +1,125 @@
+page.title=Addressing Common Issues
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#ScreenShape">Detect the Shape of the Screen</a></li>
+  <li><a href="#PeekCards">Accomodate Peek Cards</a></li>
+  <li><a href="#RelativeMeasurements">Use Relative Measurements</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>Creating a custom watch face for Android Wear is substantially different from creating
+notifications and wearable-specific activities. This class shows you how to resolve some
+issues that you may encounter as you implement your first few watch faces.</p>
+
+
+
+<h2 id="ScreenShape">Detect the Shape of the Screen</h2>
+
+<p>Some Android Wear devices have square screens, while others have round screens. Devices with
+round screens can contain an inset (or "chin") at the bottom of the screen. Your watch face
+should adapt to and take advantage of the particular shape of the screen, as described in the
+<a href="{@docRoot}design/wear/watchfaces.html">design guidelines</a>.</p>
+
+<p>Android Wear lets your watch face determine the screen shape at runtime. To detect whether
+the screen is square or round, override the <code>onApplyWindowInsets()</code> method in the
+<code>CanvasWatchFaceService.Engine</code> class as follows:</p>
+
+<pre>
+private class Engine extends CanvasWatchFaceService.Engine {
+    boolean mIsRound;
+    int mChinSize;
+
+    &#64;Override
+    public void onApplyWindowInsets(WindowInsets insets) {
+        super.onApplyWindowInsets(insets);
+        mIsRound = insets.isRound();
+        mChinSize = insets.getSystemWindowInsetBottom();
+    }
+    ...
+}
+</pre>
+
+<p>To adapt your design when you draw your watch face, check the value of the
+<code>mIsRound</code> and <code>mChinSize</code> member variables.</p>
+
+
+
+<h2 id="PeekCards">Accomodate Peek Cards</h2>
+
+<div style="float:right;margin-left:30px;width:340px">
+<img src="{@docRoot}training/wearables/watch-faces/images/AnalogNoCard.png" alt=""
+     width="160" height="145" style="margin-right:7px"/>
+<img src="{@docRoot}training/wearables/watch-faces/images/AnalogWithCard.png" alt=""
+     width="160" height="145"/>
+<p class="img-caption"><strong>Figure 1.</strong> Some analog watch faces require adjustments
+when notification cards appear.</p>
+</div>
+
+<p>When users receive a notification, the notification card may cover a significant portion of the
+screen, depending on the
+<a href="{@docRoot}training/wearables/watch-faces/drawing.html#SystemUI">system UI style</a>. Your
+watch face should adapt to these situations by ensuring that users can still tell the time while
+the notification card is present.</p>
+
+<p>Analog watch faces can make adjustments when a notification card is present, like scaling
+down the watch face to fit inside the portion of the screen not covered by the peek card. Digital
+watch faces that display the time in the area of the screen not covered by peek cards do not
+usually require adjustments. To determine the free space above the peek card so you can adapt
+your watch face, use the <code>WatchFaceService.getPeekCardPosition()</code> method.</p>
+
+<p>In ambient mode, peek cards have a transparent background. If your watch face contains details
+near the card in ambient mode, consider drawing a black rectangle over them to ensure that users
+can read the contents of the card.</p>
+
+
+
+<h2 id="SystemIndicators">Configure the System Indicators</h2>
+
+<div style="width:200px;float:right;margin-left:10px">
+<img src="{@docRoot}training/wearables/watch-faces/images/Indicators_Cropped.png" alt=""
+     width="200" height="195"/>
+<p class="img-caption" style="margin-left:25px;margin-top:-25px">
+<strong>Figure 2.</strong> The status bar.</p>
+</div>
+
+<p>To ensure that the system indicators remain visible, you can configure their position on the
+screen and whether they need background protection when you create a <code>WatchFaceStyle</code>
+instance:</p>
+
+<ul>
+<li>To set the position of the status bar, use the <code>setStatusBarGravity()</code> method.</li>
+<li>To set the position of the hotword, use the <code>setHotwordIndicatorGravity()</code>
+method.</li>
+<li>To protect the status bar and hotword with a semi-transparent gray background, use the
+<code>setViewProtection()</code> method. This is usually necessary if your watch face has a
+light background, since the system indicators are white.</li>
+</ul>
+
+<p>For more information about the system indicators, see <a
+href="{@docRoot}training/wearables/watch-faces/drawing.html#SystemUI">Configure the System UI</a>
+and read the <a href="{@docRoot}design/wear/watchfaces.html">design guidelines</a>.</p>
+
+
+
+<h2 id="RelativeMeasurements">Use Relative Measurements</h2>
+
+<p>Android Wear devices from different manufacturers feature screens with a variety of sizes and
+resolutions. Your watch face should adapt to these variations by using relative measurements
+instead of absolute pixel values.</p>
+
+<p>When you draw your watch face, obtain the size of the canvas with the {@link
+android.graphics.Canvas#getWidth Canvas.getWidth()} and {@link
+android.graphics.Canvas#getHeight Canvas.getHeight()} methods and set the positions of your
+graphic elements using values that are some fraction of the detected screen size. If you resize
+the elements of your watch face in response to a peek card, use values that are some fraction
+of the remaining space above the card to redraw your watch face.</p>
diff --git a/docs/html/training/wearables/watch-faces/performance.jd b/docs/html/training/wearables/watch-faces/performance.jd
new file mode 100644
index 0000000..68438fe
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/performance.jd
@@ -0,0 +1,160 @@
+page.title=Optimizing Performance and Battery Life
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#ReduceSize">Reduce the Size of Your Bitmap Assets</a></li>
+  <li><a href="#CombineBitmaps">Combine Bitmap Assets</a></li>
+  <li><a href="#AntiAlias">Disable Anti-Aliasing when Drawing Scaled Bitmaps</a></li>
+  <li><a href="#OutDrawing">Move Expensive Operations Outside the Drawing Method</a></li>
+  <li><a href="#SavePower">Follow Best Practices to Save Power</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>In addition to accommodating notification cards and system indicators, you need to ensure that
+the animations in your watch face run smoothly and that your service does not perform unnecessary
+computations. Watch faces in Android Wear run continuously on the device, so it is critical
+that your watch face uses power efficiently.</p>
+
+<p>This lesson provides some tips to speed up your animations and to measure and conserve
+power on the device.</p>
+
+
+
+<h2 id="ReduceSize">Reduce the Size of Your Bitmap Assets</h2>
+
+<p>Many watch faces consist of a background image and other graphic assets that are transformed
+and overlapped on top of the background image, such as clock hands and other elements of the design
+that move over time. Typically these graphic elements are rotated (and sometimes scaled) inside the
+<code>Engine.onDraw()</code> method every time the system redraws the watch face, as described in
+<a href="{@docRoot}training/wearables/watch-faces/drawing.html#Drawing">Draw Your Watch
+Face</a>.</p>
+
+<p>The larger these graphic assets are, the more computationally expensive it is to transform them.
+Transforming large graphic assets in the <code>Engine.onDraw()</code> method drastically reduces
+the frame rate at which the system can run your animations.</p>
+
+<div id="fig1" style="float:right;width:250px;margin-left:25px">
+<img src="{@docRoot}training/wearables/watch-faces/images/ClockHandFull.png" alt=""
+     width="180" height="180"/>
+<img src="{@docRoot}training/wearables/watch-faces/images/ClockHandCropped.png" alt=""
+     width="15" height="65" style="margin-left:25px"/>
+<p class="img-caption">
+<strong>Figure 1.</strong> Clock hands can be cropped to remove extra pixels.</p>
+</div>
+
+<p>To improve the performance of your watch face:</p>
+
+<ul>
+<li>Do not use graphic elements that are larger than you need.</li>
+<li>Remove extra transparent pixels around the edges.</li>
+</ul>
+
+<p>The example clock hand on the left side of <a href="#fig1">Figure 1</a> can be reduced in size
+by 97&#37;.</p>
+
+<p>Reducing the size of your bitmap assets as described in this section not only improves
+the performance of your animations, but it also saves power.</p>
+
+
+
+<h2 id="CombineBitmaps">Combine Bitmap Assets</h2>
+
+<p>If you have bitmaps that are often drawn together, consider combining them into the same
+graphic asset. You can often combine the background image in interactive mode with the tick
+marks to avoid drawing two full-screen bitmaps every time the system redraws the watch face.</p>
+
+
+
+<h2 id="AntiAlias">Disable Anti-Aliasing when Drawing Scaled Bitmaps</h2>
+
+<p>When you draw a scaled bitmap on the {@link android.graphics.Canvas} object using the {@link
+android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint)
+Canvas.drawBitmap()} method, you can provide a {@link android.graphics.Paint} instance to configure
+several options. To improve performance, disable anti-aliasing using the {@link
+android.graphics.Paint#setAntiAlias setAntiAlias()} method, since this option does not have any
+effect on bitmaps.</p>
+
+<div id="fig2" style="float:right;width:250px;margin-left:40px;margin-top:12px">
+<img src="{@docRoot}training/wearables/watch-faces/images/BitmapFilterDisabled.png" alt=""
+     width="70" height="70" style="margin-left:20px"/>
+<img src="{@docRoot}training/wearables/watch-faces/images/BitmapFilterEnabled.png" alt=""
+     width="70" height="70" style="margin-left:20px"/>
+<p class="img-caption"><strong>Figure 2.</strong> Example of bitmap filtering disabled (left) and
+enabled (right).</p>
+</div>
+
+<h3 id="BitmapFiltering">Use bitmap filtering</h3>
+
+<p>For bitmap assets that you draw on top of other elements, enable bitmap filtering on the same
+{@link android.graphics.Paint} instance using the {@link android.graphics.Paint#setFilterBitmap
+setFilterBitmap()} method. <a href="#fig2">Figure 2</a> shows a magnified view of a clock hand with
+and without bitmap filtering.</p>
+
+
+
+<h2 id="OutDrawing">Move Expensive Operations Outside the Drawing Method</h2>
+
+<p>The system calls the <code>Engine.onDraw()</code> method every time it redraws your watch
+face, so you should only include operations that are strictly required to update the watch
+face inside this method to improve performance.<p>
+
+<p>When possible, avoid performing these operations inside the <code>onDraw()</code> method:</p>
+
+<ul>
+<li>Loading images and other resources.</li>
+<li>Resizing images.</li>
+<li>Allocating objects.</li>
+<li>Performing computations whose result does not change between frames.</li>
+</ul>
+
+<p>You can usually perform these operations in the <code>Engine.onCreate()</code> method instead.
+You can resize images ahead of time in the {@link
+android.service.wallpaper.WallpaperService.Engine#onSurfaceChanged(android.view.SurfaceHolder, int, int, int)
+Engine.onSurfaceChanged()} method, which provides you with the size of the canvas.</p>
+
+<p>To analyze the performance of your watch face, use the Android Device Monitor. In particular,
+ensure that the execution time for your <code>Engine.onDraw()</code> implementation is short and
+consistent across invocations. For more information, see
+<a href="{@docRoot}tools/debugging/ddms.html">Using DDMS</a>.</p>
+
+
+
+<h2 id="SavePower">Follow Best Practices to Save Power</h2>
+
+<p>In addition to the techniques described in the previous sections, follow the best
+practices in this section to reduce the power consumption of your watch face.</p>
+
+<h3>Reduce the frame rate of animations</h3>
+
+<p>Animations are often computationally expensive and consume a significant amount of power. Most
+animations look fluid at 30 frames per second, so you should avoid running your animations
+at a higher frame rate.</p>
+
+<h3>Let the CPU sleep</h3>
+
+<p>Animations and small changes to the contents of the watch face wake up the CPU. Your watch
+face should let the CPU sleep in between animations. For example, you can use short bursts of
+animation every second in interactive mode and then let the CPU sleep until the next second.
+Letting the CPU sleep often, even briefly, can significantly reduce power consumption.</p>
+
+<p>To maximize battery life, use animations sparingly. Even a blinking colon wakes up the CPU with
+every blink and hurts battery life.</p>
+
+<h3>Monitor power consumption</h3>
+
+<p>The <a href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">
+Android Wear companion app</a> lets developers and users see how much battery different processes
+on the wearable device are consuming under <strong>Settings</strong> > <strong>Watch
+battery</strong>.</p>
+
+<p>For more information about new features in Android 5.0 that help you improve battery life,
+see <a href="{@docRoot}about/versions/android-5.0.html#Power">Project Volta</a>.</p>
diff --git a/docs/html/training/wearables/watch-faces/service.jd b/docs/html/training/wearables/watch-faces/service.jd
new file mode 100644
index 0000000..87ebefa
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/service.jd
@@ -0,0 +1,280 @@
+page.title=Building a Watch Face Service
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#CreateProject">Create and Configure Your Project</a></li>
+  <li><a href="#CallbackMethods">Implement the Service Callback Methods</a></li>
+  <li><a href="#RegisterService">Register the Service Implementation</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>Watch faces in Android Wear are implemented as <a
+href="{@docRoot}guide/components/services.html">services</a> and packaged inside a <a
+href="{@docRoot}training/wearables/apps/index.html">wearable app</a>. When users install a
+handheld app that contains a wearable app with watch faces, these watch faces become available
+in the <a
+href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
+Wear companion app</a> on the handheld device and in the watch face picker on the wearable. When
+users select one of the available watch faces, the wearable device shows the watch face and
+invokes its service callback methods as required.</p>
+
+<p>This lesson shows you how to configure an Android project to include watch faces and how
+to implement the watch face service.</p>
+
+
+
+<h2 id="CreateProject">Create and Configure Your Project</h2>
+
+<p>To create an Android project for your watch face in Android Studio:</p>
+
+<ol>
+<li>Start Android Studio.</li>
+<li>Create a new project:
+  <ul>
+  <li>If you don't have a project opened, in the <strong>Welcome</strong> screen, click
+      <strong>New Project</strong>.</li>
+  <li>If you have a project opened, from the <strong>File</strong> menu, select <strong>New
+      Project</strong>.</li>
+  </ul>
+</li>
+<li>Provide an application name and click <strong>Next</strong>.</li>
+<li>Select the <strong>Phone and Tablet</strong> form factor.</li>
+<li>Under <strong>Minimum SDK</strong>, choose API 18.</li>
+<li>Select the <strong>Wear</strong> form factor.</li>
+<li>Under <strong>Minimum SDK</strong>, choose API 21 and click <strong>Next</strong>.</li>
+<li>Select <strong>Add No Activity</strong> and click <strong>Next</strong> in the two following
+    screens.</li>
+<li>Click <strong>Finish</strong>.</li>
+<li>Click <strong>View</strong> > <strong>Tool Windows</strong> > <strong>Project</strong> in the
+    IDE window.</li>
+</ol>
+
+<p>Android Studio creates a project with the <code>wear</code> and <code>mobile</code> modules.
+For more information, see <a href="{@docRoot}sdk/installing/create-project.html">Creating a
+Project</a>.</p>
+
+<h3 id="Dependencies">Dependencies</h3>
+
+<p>For the handheld app, edit the <code>build.gradle</code> file in the <code>mobile</code> module
+to add these dependencies:</p>
+
+<pre>
+apply plugin: 'com.android.application'
+
+android { ... }
+
+dependencies {
+    ...
+    wearApp project(':wear')
+    compile 'com.google.android.gms:play-services:6.5.+'
+}
+</pre>
+
+<p>For the wearable app, edit the <code>build.gradle</code> file in the <code>wear</code> module
+to add these dependencies:</p>
+
+<pre>
+apply plugin: 'com.android.application'
+
+android { ... }
+
+dependencies {
+    ...
+    compile 'com.google.android.support:wearable:1.1.+'
+    compile 'com.google.android.gms:play-services-wearable:6.5.+'
+}
+</pre>
+
+<p>The Wearable Support Library provides the necessary classes that you extend to create watch
+face implementations. The Google Play services client libraries (<code>play-services</code> and
+<code>play-services-wearable</code>) are required to sync data items between the companion device
+and the wearable with the <a href="{@docRoot}training/wearables/data-layer/index.html">Wearable
+Data Layer API</a>.</p>
+
+<h3 id="Reference">Wearable Support Library API Reference</h3>
+
+<p>The reference documentation provides detailed information about the classes you use to
+implement watch faces. Download the
+<a href="{@docRoot}shareables/training/wearable-support-docs.zip">API reference
+documentation</a> for the Wearable Support Library.</p>
+
+<h3 id="LibEclipse">Download the Wearable Support Library for Eclipse ADT</h3>
+
+<p>If you are using the ADT plugin for Eclipse, download the
+<a href="{@docRoot}shareables/training/wearable-support-lib.zip">Wearable Support Library</a> and
+include it as a dependency in your project.</p>
+
+<h3 id="Permissions">Declare Permissions</h3>
+
+<p>Watch faces require the <code>PROVIDE_BACKGROUND</code> and <code>WAKE_LOCK</code> permissions.
+Add the following permissions to the manifest files of both the wearable app and the mobile
+app under the <code>manifest</code> element:</p>
+
+<pre>
+&lt;manifest ...>
+    &lt;uses-permission
+        android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
+    &lt;uses-permission
+        android:name="android.permission.WAKE_LOCK" />
+    ...
+&lt;/manifest>
+</pre>
+
+<p class="caution"><strong>Caution:</strong> The handheld app must include all the permissions
+declared in the wearable app.</p>
+
+
+
+<h2 id="CallbackMethods">Implement the Service and Callback Methods</h2>
+
+<p>Watch faces in Android Wear are implemented as
+<a href="{@docRoot}guide/components/services.html">services</a>.
+When a watch face is active, the system invokes the methods in its service when the time changes
+or when an important event occurs (like switching to ambient mode or receiving a new
+notification). The service implementation then draws the watch face on the screen using the
+updated time and any other relevant data.</p>
+
+<p>To implement a watch face, you extend the <code>CanvasWatchFaceService</code>
+and <code>CanvasWatchFaceService.Engine</code> classes, and then you override the callback methods
+in the <code>CanvasWatchFaceService.Engine</code> class. These classes are included in the
+Wearable Support Library.</p>
+
+<p>The following snippet outlines the key methods you need to implement:</p>
+
+<pre>
+public class AnalogWatchFaceService extends CanvasWatchFaceService {
+
+    &#64;Override
+    public Engine onCreateEngine() {
+        /* provide your watch face implementation */
+        return new Engine();
+    }
+
+    /* implement service callback methods */
+    private class Engine extends CanvasWatchFaceService.Engine {
+
+        &#64;Override
+        public void onCreate(SurfaceHolder holder) {
+            /* initialize your watch face */
+        }
+
+        &#64;Override
+        public void onPropertiesChanged(Bundle properties) {
+            /* get device features (burn-in, low-bit ambient) */
+        }
+
+        &#64;Override
+        public void onTimeTick() {
+            /* the time changed */
+        }
+
+        &#64;Override
+        public void onAmbientModeChanged(boolean inAmbientMode) {
+            /* the wearable switched between modes */
+        }
+
+        &#64;Override
+        public void onDraw(Canvas canvas, Rect bounds) {
+            /* draw your watch face */
+        }
+
+        &#64;Override
+        public void onVisibilityChanged(boolean visible) {
+            /* the watch face became visible or invisible */
+        }
+    }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> The <em>WatchFace</em> sample in the Android SDK
+demonstrates how to implement analog and digital watch faces extending the
+<code>CanvasWatchFaceService</code> class. This sample is located in the
+<code>android-sdk/samples/android-21/wearable/WatchFace</code> directory.</p>
+
+<p>The <code>CanvasWatchFaceService</code> class provides an invalidate mechanism similar to
+the {@link android.view.View#invalidate View.invalidate()} method. You can call the
+<code>invalidate()</code> method throughout your implementation when you want the system to
+redraw the watch face. You can only use the <code>invalidate()</code> method in the main UI
+thread. To invalidate the canvas from another thread, call the <code>postInvalidate()</code>
+method.</p>
+
+<p>For more information about implementing the methods in the
+<code>CanvasWatchFaceService.Engine</code> class, see <a
+href="{@docRoot}training/wearables/watch-faces/drawing.html">Drawing Watch Faces</a>.</p>
+
+
+
+<h2 id="RegisterService">Register the Watch Face Service</h2>
+
+<p>After you implement the watch face service, you register the implementation in the manifest
+file of the wearable app. When users install this app, the system uses the information about
+the service to make the watch face available in the <a
+href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
+Wear companion app</a> and in the watch face picker on the wearable device.</p>
+
+</p>The following snippet shows how to register a watch face implementation
+under the <a href="{@docRoot}guide/topics/manifest/application-element.html">
+<code>application</code></a> element:</p>
+
+<pre>
+&lt;service
+    android:name=".AnalogWatchFaceService"
+    android:label="&#64;string/analog_name"
+    android:allowEmbedded="true"
+    android:taskAffinity=""
+    android:permission="android.permission.BIND_WALLPAPER" >
+    &lt;meta-data
+        android:name="android.service.wallpaper"
+        android:resource="&#64;xml/watch_face" />
+    &lt;meta-data
+        android:name="com.google.android.wearable.watchface.preview"
+        android:resource="&#64;drawable/preview_analog" />
+    &lt;meta-data
+        android:name="com.google.android.wearable.watchface.preview_circular"
+        android:resource="&#64;drawable/preview_analog_circular" />
+    &lt;intent-filter>
+        &lt;action android:name="android.service.wallpaper.WallpaperService" />
+        &lt;category
+            android:name=
+            "com.google.android.wearable.watchface.category.WATCH_FACE" />
+    &lt;/intent-filter>
+&lt;/service>
+</pre>
+
+<p>The <a
+href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
+Wear companion app</a> and the watch face picker on the wearable device use the preview image
+defined by the <code>com.google.android.wearable.watchface.preview</code> metadata entry when
+presenting users with all the watch faces installed on the device. To obtain this drawable,
+run the watch face on your Android Wear device or in an emulator instance and <a
+href="{@docRoot}sdk/installing/studio-debug.html#screenCap">take a screenshot</a>. On Android Wear
+devices with hdpi screens, the preview image is typically 320x320 pixels in size.</p>
+
+<p>Watch faces that look substantially different on round devices can provide both round and
+square preview images. To specify a round preview image, use the
+<code>com.google.android.wearable.watchface.preview_circular</code> metadata entry. If a watch
+face includes both preview images, the companion app and the watch face picker on the wearable
+show the appropriate one, depending on the shape of the watch. If a round preview image is not
+included, the square preview image is used for both square and round devices. For round devices,
+a square preview image is cropped using a circular shape.</p>
+
+<p>The <code>android.service.wallpaper</code> metadata entry specifies the
+<code>watch_face.xml</code> resource file, which contains a <code>wallpaper</code>
+element:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
+</pre>
+
+<p>Your wearable app can contain more than one watch face. You must add a service entry to the
+manifest file of the wearable app for each of your watch face implementations.</p>
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 9eb0251..74ff1b0 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -375,7 +375,7 @@
                 mOneShot = orig.mOneShot;
             } else {
                 mDurations = new int[getCapacity()];
-                mOneShot = true;
+                mOneShot = false;
             }
         }
 
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 79ac651..9be296a 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -48,6 +48,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.Collection;
 
 /**
  * A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a
@@ -913,8 +914,11 @@
         }
 
         @Override
-        public Bitmap getBitmap() {
-            return mBitmap;
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            if (isAtlasable(mBitmap) && atlasList.add(mBitmap)) {
+                return mBitmap.getWidth() * mBitmap.getHeight();
+            }
+            return 0;
         }
 
         @Override
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 0f0c844..e3b50ea 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -252,6 +252,11 @@
     }
 
     @Override
+    public boolean canApplyTheme() {
+        return mColorState.canApplyTheme() || super.canApplyTheme();
+    }
+
+    @Override
     public void applyTheme(Theme t) {
         super.applyTheme(t);
 
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 1fac5b6..0e38cc0 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -51,6 +51,7 @@
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
+import java.util.Collection;
 
 /**
  * A Drawable is a general abstraction for "something that can be drawn."  Most
@@ -1244,10 +1245,16 @@
         public abstract int getChangingConfigurations();
 
         /**
+         * @return Total pixel count
          * @hide
          */
-        public Bitmap getBitmap() {
-            return null;
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            return 0;
+        }
+
+        /** @hide */
+        protected final boolean isAtlasable(Bitmap bitmap) {
+            return bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888;
         }
 
         /**
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 2748030..39ef10c 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -20,6 +20,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
@@ -31,6 +32,8 @@
 import android.util.LayoutDirection;
 import android.util.SparseArray;
 
+import java.util.Collection;
+
 /**
  * A helper class that contains several {@link Drawable}s and selects which one to use.
  *
@@ -444,36 +447,10 @@
             mCurrDrawable = d;
             mCurIndex = idx;
             if (d != null) {
-                d.mutate();
                 if (mDrawableContainerState.mEnterFadeDuration > 0) {
                     mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
-                } else if (mHasAlpha) {
-                    d.setAlpha(mAlpha);
                 }
-                if (mDrawableContainerState.mHasColorFilter) {
-                    // Color filter always overrides tint.
-                    d.setColorFilter(mDrawableContainerState.mColorFilter);
-                } else {
-                    if (mDrawableContainerState.mHasTintList) {
-                        d.setTintList(mDrawableContainerState.mTintList);
-                    }
-                    if (mDrawableContainerState.mHasTintMode) {
-                        d.setTintMode(mDrawableContainerState.mTintMode);
-                    }
-                }
-                d.setVisible(isVisible(), true);
-                d.setDither(mDrawableContainerState.mDither);
-                d.setState(getState());
-                d.setLevel(getLevel());
-                d.setBounds(getBounds());
-                d.setLayoutDirection(getLayoutDirection());
-                d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
-
-                final Rect hotspotBounds = mHotspotBounds;
-                if (hotspotBounds != null) {
-                    d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top,
-                            hotspotBounds.right, hotspotBounds.bottom);
-                }
+                initializeDrawableForDisplay(d);
             }
         } else {
             mCurrDrawable = null;
@@ -500,6 +477,45 @@
         return true;
     }
 
+    /**
+     * Initializes a drawable for display in this container.
+     *
+     * @param d The drawable to initialize.
+     */
+    private void initializeDrawableForDisplay(Drawable d) {
+        d.mutate();
+
+        if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) {
+            d.setAlpha(mAlpha);
+        }
+
+        if (mDrawableContainerState.mHasColorFilter) {
+            // Color filter always overrides tint.
+            d.setColorFilter(mDrawableContainerState.mColorFilter);
+        } else {
+            if (mDrawableContainerState.mHasTintList) {
+                d.setTintList(mDrawableContainerState.mTintList);
+            }
+            if (mDrawableContainerState.mHasTintMode) {
+                d.setTintMode(mDrawableContainerState.mTintMode);
+            }
+        }
+
+        d.setVisible(isVisible(), true);
+        d.setDither(mDrawableContainerState.mDither);
+        d.setState(getState());
+        d.setLevel(getLevel());
+        d.setBounds(getBounds());
+        d.setLayoutDirection(getLayoutDirection());
+        d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+
+        final Rect hotspotBounds = mHotspotBounds;
+        if (hotspotBounds != null) {
+            d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top,
+                    hotspotBounds.right, hotspotBounds.bottom);
+        }
+    }
+
     void animate(boolean schedule) {
         mHasAlpha = true;
 
@@ -711,10 +727,17 @@
                     mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
                 }
 
+                // Create futures for drawables with constant states. If a
+                // drawable doesn't have a constant state, then we can't clone
+                // it and we'll have to reference the original.
                 final int N = mNumChildren;
                 for (int i = 0; i < N; i++) {
                     if (origDr[i] != null) {
-                        mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+                        if (origDr[i].getConstantState() != null) {
+                            mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+                        } else {
+                            mDrawables[i] = origDr[i];
+                        }
                     }
                 }
             } else {
@@ -1062,6 +1085,20 @@
             return true;
         }
 
+        /** @hide */
+        @Override
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            final int N = mNumChildren;
+            int pixelCount = 0;
+            for (int i = 0; i < N; i++) {
+                final ConstantState state = getChild(i).getConstantState();
+                if (state != null) {
+                    pixelCount += state.addAtlasableBitmaps(atlasList);
+                }
+            }
+            return pixelCount;
+        }
+
         /**
          * Class capable of cloning a Drawable from another Drawable's
          * ConstantState.
@@ -1112,9 +1149,14 @@
         // The locally cached drawables may have changed.
         if (mCurIndex >= 0) {
             mCurrDrawable = state.getChild(mCurIndex);
+            if (mCurrDrawable != null) {
+                initializeDrawableForDisplay(mCurrDrawable);
+            }
         }
-        if (mLastIndex >= 0) {
-            mLastDrawable = state.getChild(mLastIndex);
-        }
+
+        // Clear out the last drawable. We don't have enough information to
+        // propagate local state from the past.
+        mLastIndex = -1;
+        mLastDrawable = null;
     }
 }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 94c7026..cb42397 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1795,5 +1795,7 @@
                 mStrokePaint.setPathEffect(e);
             }
         }
+
+        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
     }
 }
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index acfd427..8b70a08 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -19,6 +19,7 @@
 import com.android.internal.R;
 
 import android.annotation.NonNull;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -26,16 +27,19 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable.ConstantState;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 
 import java.io.IOException;
+import java.util.Collection;
 
 /**
  * A Drawable that insets another Drawable by a specified distance.
@@ -472,6 +476,15 @@
 
             return mCanConstantState;
         }
+
+        @Override
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            final ConstantState state = mDrawable.getConstantState();
+            if (state != null) {
+                return state.addAtlasableBitmaps(atlasList);
+            }
+            return 0;
+        }
     }
 
     private InsetDrawable(InsetState state, Resources res) {
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 689d225..4aa5f59 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Outline;
@@ -36,6 +37,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.Collection;
 
 /**
  * A Drawable that manages an array of other Drawables. These are drawn in array
@@ -1105,6 +1107,20 @@
             mHaveOpacity = false;
             mHaveIsStateful = false;
         }
+
+        @Override
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            final ChildDrawable[] array = mChildren;
+            final int N = mNum;
+            int pixelCount = 0;
+            for (int i = 0; i < N; i++) {
+                final ConstantState state = array[i].mDrawable.getConstantState();
+                if (state != null) {
+                    pixelCount += state.addAtlasableBitmaps(atlasList);
+                }
+            }
+            return pixelCount;
+        }
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index d821224..b87ae92 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -48,6 +48,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collection;
 
 /**
  *
@@ -289,7 +290,7 @@
         if (bounds.isEmpty()) return;
 
         if (mNinePatchState != null) {
-            NinePatch.InsetStruct insets = mNinePatchState.getBitmap().getNinePatchInsets();
+            NinePatch.InsetStruct insets = mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
             if (insets != null) {
                 final Rect outlineInsets = insets.outlineRect;
                 outline.setRoundRect(bounds.left + outlineInsets.left,
@@ -648,8 +649,12 @@
         }
 
         @Override
-        public Bitmap getBitmap() {
-            return mNinePatch.getBitmap();
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            final Bitmap bitmap = mNinePatch.getBitmap();
+            if (isAtlasable(bitmap) && atlasList.add(bitmap)) {
+                return bitmap.getWidth() * bitmap.getHeight();
+            }
+            return 0;
         }
 
         @Override
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index a3a220c..ba1e86c 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -214,7 +214,7 @@
         final boolean canUseHardware = c.isHardwareAccelerated();
         if (mCanUseHardware != canUseHardware && mCanUseHardware) {
             // We've switched from hardware to non-hardware mode. Panic.
-            cancelHardwareAnimations(true);
+            cancelHardwareAnimations(false);
         }
         mCanUseHardware = canUseHardware;
 
@@ -493,7 +493,7 @@
     public void cancel() {
         mCanceled = true;
         cancelSoftwareAnimations();
-        cancelHardwareAnimations(true);
+        cancelHardwareAnimations(false);
         mCanceled = false;
     }
 
@@ -522,15 +522,30 @@
     /**
      * Cancels any running hardware animations.
      */
-    private void cancelHardwareAnimations(boolean cancelPending) {
+    private void cancelHardwareAnimations(boolean jumpToEnd) {
         final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
         final int N = runningAnimations.size();
         for (int i = 0; i < N; i++) {
-            runningAnimations.get(i).cancel();
+            if (jumpToEnd) {
+                runningAnimations.get(i).end();
+            } else {
+                runningAnimations.get(i).cancel();
+            }
         }
         runningAnimations.clear();
 
-        mHasPendingHardwareExit = false;
+        if (mHasPendingHardwareExit) {
+            // If we had a pending hardware exit, jump to the end state.
+            mHasPendingHardwareExit = false;
+
+            if (jumpToEnd) {
+                mOpacity = 0;
+                mTweenX = 1;
+                mTweenY = 1;
+                mTweenRadius = 1;
+            }
+        }
+
         mHardwareAnimating = false;
     }
 
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 665d736..cc42aac 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -148,7 +148,7 @@
         final boolean canUseHardware = c.isHardwareAccelerated();
         if (mCanUseHardware != canUseHardware && mCanUseHardware) {
             // We've switched from hardware to non-hardware mode. Panic.
-            cancelHardwareAnimations(true);
+            cancelHardwareAnimations(false);
         }
         mCanUseHardware = canUseHardware;
 
@@ -399,7 +399,7 @@
      */
     public void cancel() {
         cancelSoftwareAnimations();
-        cancelHardwareAnimations(true);
+        cancelHardwareAnimations(false);
     }
 
     private void cancelSoftwareAnimations() {
@@ -412,15 +412,27 @@
     /**
      * Cancels any running hardware animations.
      */
-    private void cancelHardwareAnimations(boolean cancelPending) {
+    private void cancelHardwareAnimations(boolean jumpToEnd) {
         final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
         final int N = runningAnimations.size();
         for (int i = 0; i < N; i++) {
-            runningAnimations.get(i).cancel();
+            if (jumpToEnd) {
+                runningAnimations.get(i).end();
+            } else {
+                runningAnimations.get(i).cancel();
+            }
         }
         runningAnimations.clear();
 
-        mHasPendingHardwareExit = false;
+        if (mHasPendingHardwareExit) {
+            // If we had a pending hardware exit, jump to the end state.
+            mHasPendingHardwareExit = false;
+
+            if (jumpToEnd) {
+                mOuterOpacity = 0;
+            }
+        }
+
         mHardwareAnimating = false;
     }
 
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index d6d4cb8..da722f3 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -31,6 +31,7 @@
 import android.util.AttributeSet;
 
 import java.io.IOException;
+import java.util.Collection;
 
 /**
  * A Drawable that changes the size of another Drawable based on its current
@@ -413,6 +414,15 @@
 
             return mCanConstantState;
         }
+
+        @Override
+        public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
+            final ConstantState state = mDrawable.getConstantState();
+            if (state != null) {
+                return state.addAtlasableBitmaps(atlasList);
+            }
+            return 0;
+        }
     }
 
     private ScaleDrawable(ScaleState state, Resources res) {
diff --git a/include/androidfw/AttributeFinder.h b/include/androidfw/AttributeFinder.h
index a0ffeb3..acf7056 100644
--- a/include/androidfw/AttributeFinder.h
+++ b/include/androidfw/AttributeFinder.h
@@ -64,6 +64,7 @@
     void jumpToClosestAttribute(uint32_t packageId);
     void markCurrentPackageId(uint32_t packageId);
 
+    bool mFirstTime;
     Iterator mBegin;
     Iterator mEnd;
     Iterator mCurrent;
@@ -81,7 +82,8 @@
 
 template <typename Derived, typename Iterator> inline
 BackTrackingAttributeFinder<Derived, Iterator>::BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end)
-    : mBegin(begin)
+    : mFirstTime(true)
+    , mBegin(begin)
     , mEnd(end)
     , mCurrent(begin)
     , mLargest(begin)
@@ -145,8 +147,11 @@
         return mEnd;
     }
 
-    if (mCurrentAttr == 0) {
-        // One-time initialization.
+    if (mFirstTime) {
+        // One-time initialization. We do this here instead of the constructor
+        // because the derived class we access in getAttribute() may not be
+        // fully constructed.
+        mFirstTime = false;
         mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mBegin);
         mLastPackageId = getPackage(mCurrentAttr);
         markCurrentPackageId(mLastPackageId);
diff --git a/libs/androidfw/tests/AttributeFinder_test.cpp b/libs/androidfw/tests/AttributeFinder_test.cpp
index 664709c..5054624 100644
--- a/libs/androidfw/tests/AttributeFinder_test.cpp
+++ b/libs/androidfw/tests/AttributeFinder_test.cpp
@@ -50,6 +50,10 @@
         0x01010002, 0x01010004, 0x7f010001
 };
 
+static const uint32_t singlePackageAttributes[] = {
+        0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000
+};
+
 TEST(AttributeFinderTest, IteratesSequentially) {
     const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
     MockAttributeFinder finder(sortedAttributes, end);
@@ -109,3 +113,16 @@
     EXPECT_EQ(1, finder.find(0x02010010));
     EXPECT_EQ(6, finder.find(0x7f010001));
 }
+
+TEST(AttributeFinderTest, FindAttributesInSinglePackageAttributeList) {
+    const int end = sizeof(singlePackageAttributes) / sizeof(*singlePackageAttributes);
+    MockAttributeFinder finder(singlePackageAttributes, end);
+
+    EXPECT_EQ(end, finder.find(0x010100f4));
+    EXPECT_EQ(end, finder.find(0x010100f5));
+    EXPECT_EQ(end, finder.find(0x010100f6));
+    EXPECT_EQ(end, finder.find(0x010100f7));
+    EXPECT_EQ(end, finder.find(0x010100f8));
+    EXPECT_EQ(end, finder.find(0x010100fa));
+    EXPECT_EQ(0, finder.find(0x7f010007));
+}
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 21c869b..b2dba00 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -325,6 +325,7 @@
     // At the end, update the real index and vertex buffer size.
     shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
     shadowVertexBuffer.updateIndexCount(indexBufferIndex);
+    shadowVertexBuffer.computeBounds<AlphaVertex>();
 
     ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Ambient Vertex Buffer");
     ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Ambient Index Buffer");
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index e5a93bd..52ca92d 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -36,39 +36,43 @@
     ATRACE_NAME("AssetAtlas::init");
 
     mImage = new Image(buffer);
-
     if (mImage->getTexture()) {
-        Caches& caches = Caches::getInstance();
-
-        mTexture = new Texture(caches);
-        mTexture->id = mImage->getTexture();
-        mTexture->width = buffer->getWidth();
-        mTexture->height = buffer->getHeight();
-
-        createEntries(caches, map, count);
+        if (!mTexture) {
+            Caches& caches = Caches::getInstance();
+            mTexture = new Texture(caches);
+            mTexture->width = buffer->getWidth();
+            mTexture->height = buffer->getHeight();
+            createEntries(caches, map, count);
+        }
     } else {
         ALOGW("Could not create atlas image");
-
         delete mImage;
         mImage = NULL;
-        mTexture = NULL;
     }
 
-    mGenerationId++;
+    updateTextureId();
 }
 
 void AssetAtlas::terminate() {
     if (mImage) {
         delete mImage;
         mImage = NULL;
+        updateTextureId();
+    }
+}
 
-        delete mTexture;
-        mTexture = NULL;
 
-        for (size_t i = 0; i < mEntries.size(); i++) {
-            delete mEntries.valueAt(i);
-        }
-        mEntries.clear();
+void AssetAtlas::updateTextureId() {
+    mTexture->id = mImage ? mImage->getTexture() : 0;
+    if (mTexture->id) {
+        // Texture ID changed, force-set to defaults to sync the wrapper & GL
+        // state objects
+        mTexture->setWrap(GL_CLAMP_TO_EDGE, false, true);
+        mTexture->setFilter(GL_NEAREST, false, true);
+    }
+    for (size_t i = 0; i < mEntries.size(); i++) {
+        AssetAtlas::Entry* entry = mEntries.valueAt(i);
+        entry->texture->id = mTexture->id;
     }
 }
 
@@ -133,7 +137,6 @@
                 y / height, (y + bitmap->height()) / height);
 
         Texture* texture = new DelegateTexture(caches, mTexture);
-        texture->id = mTexture->id;
         texture->blend = !bitmap->isOpaque();
         texture->width = bitmap->width();
         texture->height = bitmap->height();
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 2ec556e..fffd740 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -106,7 +106,7 @@
         friend class AssetAtlas;
     };
 
-    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+    AssetAtlas(): mTexture(NULL), mImage(NULL),
             mBlendKey(true), mOpaqueKey(false) { }
     ~AssetAtlas() { terminate(); }
 
@@ -130,7 +130,7 @@
      * After calling this method, the width, height
      * and texture are set to 0.
      */
-    ANDROID_API void terminate();
+    void terminate();
 
     /**
      * Returns the width of this atlas in pixels.
@@ -168,21 +168,13 @@
      */
     Texture* getEntryTexture(const SkBitmap* bitmap) const;
 
-    /**
-     * Returns the current generation id of the atlas.
-     */
-    uint32_t getGenerationId() const {
-        return mGenerationId;
-    }
-
 private:
     void createEntries(Caches& caches, int64_t* map, int count);
+    void updateTextureId();
 
     Texture* mTexture;
     Image* mImage;
 
-    uint32_t mGenerationId;
-
     const bool mBlendKey;
     const bool mOpaqueKey;
 
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 6453206..4bbe6ed 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -237,8 +237,6 @@
     programCache.clear();
     currentProgram = NULL;
 
-    assetAtlas.terminate();
-
     patchCache.clear();
 
     clearGarbage();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e338686..2e179af 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -348,8 +348,6 @@
     Dither dither;
     Stencil stencil;
 
-    AssetAtlas assetAtlas;
-
     bool gpuPixelBuffersEnabled;
 
     // Debug methods
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index cb8a8d1..7a43a2a 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -77,18 +77,14 @@
     OpenGLRenderer& mRenderer;
     const int mReplayFlags;
 
-    // Allocator with the lifetime of a single frame.
-    // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator
+    // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
+    // while defer shares the DeferredDisplayList's Allocator
+    // TODO: move this allocator to be owned by object with clear frame lifecycle
     LinearAllocator * const mAllocator;
 
     SkPath* allocPathForFrame() {
-        mTempPaths.push_back();
-        return &mTempPaths.back();
+        return mRenderer.allocPathForFrame();
     }
-
-private:
-    // Paths kept alive for the duration of the frame
-    std::vector<SkPath> mTempPaths;
 };
 
 class DeferStateStruct : public PlaybackStateStruct {
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index d78c1cb..8a5e21d 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -32,6 +32,7 @@
 #include "AssetAtlas.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListRenderer.h"
+#include "RenderState.h"
 #include "UvMapper.h"
 #include "utils/LinearAllocator.h"
 
@@ -647,24 +648,17 @@
     DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
             : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
             , mBitmap(bitmap)
-            , mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mUvMapper = mEntry->uvMapper;
-        }
+            , mEntryValid(false), mEntry(NULL) {
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         return renderer.drawBitmap(mBitmap, getPaint(renderer));
     }
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
-            mUvMapper = mEntry->uvMapper;
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -700,7 +694,7 @@
             pureTranslate &= state.mMatrix.isPureTranslate();
 
             Rect texCoords(0, 0, 1, 1);
-            ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
+            ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords);
 
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
@@ -720,7 +714,8 @@
     }
 
     virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
+        OP_LOG("Draw bitmap %p at %f %f%s", mBitmap, mLocalBounds.left, mLocalBounds.top,
+                mEntry ? " using AssetAtlas" : "");
     }
 
     virtual const char* name() { return "DrawBitmap"; }
@@ -728,7 +723,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry() ?
+        deferInfo.mergeId = getAtlasEntry(renderer) ?
                 (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
         // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
@@ -741,13 +736,17 @@
                 (mBitmap->colorType() != kAlpha_8_SkColorType);
     }
 
+    void uvMap(OpenGLRenderer& renderer, Rect& texCoords) {
+        if (getAtlasEntry(renderer)) {
+            mEntry->uvMapper.map(texCoords);
+        }
+    }
+
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
     const SkBitmap* mBitmap;
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
-    UvMapper mUvMapper;
 };
 
 class DrawBitmapRectOp : public DrawBoundedOp {
@@ -840,18 +839,13 @@
             float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
             mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
-            mAtlas(Caches::getInstance().assetAtlas) {
-        mEntry = mAtlas.getEntry(bitmap);
-        if (mEntry) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-        }
+            mEntryValid(false), mEntry(NULL) {
     };
 
-    AssetAtlas::Entry* getAtlasEntry() {
-        // The atlas entry is stale, let's get a new one
-        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
-            mEntryGenerationId = mAtlas.getGenerationId();
-            mEntry = mAtlas.getEntry(mBitmap);
+    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
+        if (!mEntryValid) {
+            mEntryValid = true;
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
         }
         return mEntry;
     }
@@ -859,7 +853,7 @@
     const Patch* getMesh(OpenGLRenderer& renderer) {
         if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
             PatchCache& cache = renderer.getCaches().patchCache;
-            mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
+            mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(),
                     mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
             mGenerationId = cache.getGenerationId();
         }
@@ -941,20 +935,21 @@
             indexCount += opMesh->indexCount;
         }
 
-        return renderer.drawPatches(mBitmap, getAtlasEntry(),
+        return renderer.drawPatches(mBitmap, getAtlasEntry(renderer),
                 &vertices[0], indexCount, getPaint(renderer));
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         // We're not calling the public variant of drawPatch() here
         // This method won't perform the quickReject() since we've already done it at this point
-        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer),
                 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
                 getPaint(renderer));
     }
 
     virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("Draw patch " RECT_STRING, RECT_ARGS(mLocalBounds));
+        OP_LOG("Draw patch " RECT_STRING "%s", RECT_ARGS(mLocalBounds),
+                mEntry ? " with AssetAtlas" : "");
     }
 
     virtual const char* name() { return "DrawPatch"; }
@@ -962,7 +957,7 @@
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
         deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
         deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
@@ -975,8 +970,7 @@
     uint32_t mGenerationId;
     const Patch* mMesh;
 
-    const AssetAtlas& mAtlas;
-    uint32_t mEntryGenerationId;
+    bool mEntryValid;
     AssetAtlas::Entry* mEntry;
 };
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 075f2c5..7285496 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -311,6 +311,11 @@
     renderOverdraw();
     endTiling();
 
+    for (size_t i = 0; i < mTempPaths.size(); i++) {
+        delete mTempPaths[i];
+    }
+    mTempPaths.clear();
+
     // When finish() is invoked on FBO 0 we've reached the end
     // of the current frame
     if (getTargetFbo() == 0) {
@@ -2049,7 +2054,7 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     const UvMapper& mapper(getMapper(texture));
 
     for (int32_t y = 0; y < meshHeight; y++) {
@@ -2232,7 +2237,7 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
+    AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap);
     const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
             right - left, bottom - top, patch);
 
@@ -3028,7 +3033,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
     }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e1c3d10..5eee2e2 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -342,6 +342,12 @@
     uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
     uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
 
+    SkPath* allocPathForFrame() {
+        SkPath* path = new SkPath();
+        mTempPaths.push_back(path);
+        return path;
+    }
+
 protected:
     /**
      * Perform the setup specific to a frame. This method does not
@@ -1014,6 +1020,9 @@
     uint8_t mAmbientShadowAlpha;
     uint8_t mSpotShadowAlpha;
 
+    // Paths kept alive for the duration of the frame
+    std::vector<SkPath*> mTempPaths;
+
     friend class Layer;
     friend class TextSetupFunctor;
     friend class DrawBitmapOp;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 810e487..787ee62 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -429,9 +429,9 @@
                 clipFlags = 0; // all clipping done by saveLayer
             }
 
-            ATRACE_FORMAT("%s alpha caused %ssaveLayer %ux%u",
+            ATRACE_FORMAT("%s alpha caused %ssaveLayer %dx%d",
                     getName(), clipFlags ? "" : "unclipped ",
-                    layerBounds.getWidth(), layerBounds.getHeight());
+                    (int)layerBounds.getWidth(), (int)layerBounds.getHeight());
 
             SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
                     layerBounds.left, layerBounds.top, layerBounds.right, layerBounds.bottom,
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index a8cf26f..d1f5f4e 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -38,6 +38,7 @@
     mCaches = &Caches::getInstance();
     mCaches->init();
     mCaches->setRenderState(this);
+    mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
 }
 
 void RenderState::onGLContextDestroyed() {
@@ -72,6 +73,7 @@
         LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
     }
 */
+    mAssetAtlas.terminate();
 }
 
 void RenderState::setViewport(GLsizei width, GLsizei height) {
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index afeef95..1ecfb1c 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -23,6 +23,7 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
+#include "AssetAtlas.h"
 #include "Caches.h"
 #include "utils/Macros.h"
 
@@ -73,6 +74,8 @@
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
 
+    AssetAtlas& assetAtlas() { return mAssetAtlas; }
+
 private:
     friend class renderthread::RenderThread;
     friend class Caches;
@@ -86,6 +89,7 @@
 
     renderthread::RenderThread& mRenderThread;
     Caches* mCaches;
+    AssetAtlas mAssetAtlas;
     std::set<const Layer*> mActiveLayers;
     std::set<renderthread::CanvasContext*> mRegisteredContexts;
 
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 717ce9a..31bd637 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -68,8 +68,6 @@
 }
 
 void ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalRef();
-    SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
 
@@ -92,8 +90,6 @@
 }
 
 void ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalRef();
-    SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
 
@@ -111,8 +107,6 @@
 }
 
 void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalUnref();
-    SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
 
@@ -138,8 +132,6 @@
 }
 
 void ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
-    bitmapResource->pixelRef()->globalUnref();
-    SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 5bad2fc..63454d8 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
 
 #include <utils/Mutex.h>
 
+#include "AssetAtlas.h"
 #include "Caches.h"
 #include "TextureCache.h"
 #include "Properties.h"
@@ -39,7 +40,7 @@
 TextureCache::TextureCache():
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
-        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
+        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE), mAssetAtlas(0) {
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
         INIT_LOGD("  Setting texture cache size to %sMB", property);
@@ -62,7 +63,7 @@
 
 TextureCache::TextureCache(uint32_t maxByteSize):
         mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity),
-        mSize(0), mMaxSize(maxByteSize) {
+        mSize(0), mMaxSize(maxByteSize), mAssetAtlas(0) {
     init();
 }
 
@@ -124,6 +125,10 @@
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
+void TextureCache::setAssetAtlas(AssetAtlas* assetAtlas) {
+    mAssetAtlas = assetAtlas;
+}
+
 void TextureCache::resetMarkInUse() {
     LruCache<uint32_t, Texture*>::Iterator iter(mCache);
     while (iter.next()) {
@@ -143,6 +148,13 @@
 // Returns a prepared Texture* that either is already in the cache or can fit
 // in the cache (and is thus added to the cache)
 Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) {
+    if (CC_LIKELY(mAssetAtlas)) {
+        AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap);
+        if (CC_UNLIKELY(entry)) {
+            return entry->texture;
+        }
+    }
+
     Texture* texture = mCache.get(bitmap->pixelRef()->getStableID());
 
     if (!texture) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 3e94d1f..cf8d134 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -44,6 +44,8 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
+class AssetAtlas;
+
 /**
  * A simple LRU texture cache. The cache has a maximum size expressed in bytes.
  * Any texture added to the cache causing the cache to grow beyond the maximum
@@ -123,6 +125,8 @@
      */
     void setFlushRate(float flushRate);
 
+    void setAssetAtlas(AssetAtlas* assetAtlas);
+
 private:
 
     bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
@@ -155,6 +159,8 @@
 
     Vector<uint32_t> mGarbage;
     mutable Mutex mLock;
+
+    AssetAtlas* mAssetAtlas;
 }; // class TextureCache
 
 }; // namespace uirenderer
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 378cf61..8fb1b10 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -175,7 +175,8 @@
 
 void EglManager::initAtlas() {
     if (mAtlasBuffer.get()) {
-        Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize);
+        mRenderThread.renderState().assetAtlas().init(mAtlasBuffer,
+                mAtlasMap, mAtlasMapSize);
     }
 }
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b99b4fd..f0150d4 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1159,8 +1159,13 @@
         synchronized (mHdmiManager) {
             if (!mHdmiSystemAudioSupported) return;
             synchronized (mHdmiTvClient) {
-                mHdmiTvClient.setSystemAudioVolume(
-                        (oldVolume + 5) / 10, (newVolume + 5) / 10, maxVolume);
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mHdmiTvClient.setSystemAudioVolume(
+                            (oldVolume + 5) / 10, (newVolume + 5) / 10, maxVolume);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         }
     }
@@ -1538,15 +1543,14 @@
     private void setSystemAudioMute(boolean state) {
         if (mHdmiManager == null || mHdmiTvClient == null) return;
         synchronized (mHdmiManager) {
-            final long token = Binder.clearCallingIdentity();
-            try {
-                synchronized (mHdmiTvClient) {
-                    if (mHdmiSystemAudioSupported) {
-                        mHdmiTvClient.setSystemAudioMute(state);
-                    }
+            if (!mHdmiSystemAudioSupported) return;
+            synchronized (mHdmiTvClient) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mHdmiTvClient.setSystemAudioMute(state);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
                 }
-            } finally {
-                Binder.restoreCallingIdentity(token);
             }
         }
     }
@@ -4299,6 +4303,13 @@
                             }
                         }
                     }
+
+                    synchronized (mAudioPolicies) {
+                        for(AudioPolicyProxy policy : mAudioPolicies.values()) {
+                            policy.connectMixes();
+                        }
+                    }
+
                     // indicate the end of reconfiguration phase to audio HAL
                     AudioSystem.setParameters("restarting=false");
                     break;
@@ -5939,7 +5950,7 @@
             if (mHasFocusListener) {
                 mMediaFocusControl.addFocusFollower(mPolicyToken);
             }
-            updateMixes(AudioSystem.DEVICE_STATE_AVAILABLE);
+            connectMixes();
         }
 
         public void binderDied() {
@@ -5961,23 +5972,11 @@
             if (mHasFocusListener) {
                 mMediaFocusControl.removeFocusFollower(mPolicyToken);
             }
-            updateMixes(AudioSystem.DEVICE_STATE_UNAVAILABLE);
+            AudioSystem.registerPolicyMixes(mMixes, false);
         }
 
-        void updateMixes(int connectionState) {
-            for (AudioMix mix : mMixes) {
-                // TODO implement sending the mix attribute matching info to native audio policy
-                if (DEBUG_AP) {
-                    Log.v(TAG, "AudioPolicyProxy mix new connection state=" + connectionState
-                            + " addr=" + mix.getRegistration());
-                }
-                AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX,
-                        connectionState,
-                        mix.getRegistration());
-                AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX,
-                        connectionState,
-                        mix.getRegistration());
-            }
+        void connectMixes() {
+            AudioSystem.registerPolicyMixes(mMixes, true);
         }
     };
 
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index e795fa7..46ab7e0 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.media.audiopolicy.AudioMix;
 import java.util.ArrayList;
 
 /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
@@ -566,5 +567,7 @@
     public static final int AUDIO_HW_SYNC_INVALID = 0;
 
     public static native int getAudioHwSyncForSession(int sessionId);
+
+    public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register);
 }
 
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 400c082..8d6a588 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -578,7 +578,11 @@
         @Override
         public int getWidth() {
             if (mIsImageValid) {
-                return ImageReader.this.mWidth;
+                if (mWidth == -1) {
+                    mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() :
+                            nativeGetWidth();
+                }
+                return mWidth;
             } else {
                 throw new IllegalStateException("Image is already released");
             }
@@ -587,7 +591,11 @@
         @Override
         public int getHeight() {
             if (mIsImageValid) {
-                return ImageReader.this.mHeight;
+                if (mHeight == -1) {
+                    mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() :
+                            nativeGetHeight();
+                }
+                return mHeight;
             } else {
                 throw new IllegalStateException("Image is already released");
             }
@@ -721,9 +729,13 @@
 
         private SurfacePlane[] mPlanes;
         private boolean mIsImageValid;
+        private int mHeight = -1;
+        private int mWidth = -1;
 
         private synchronized native ByteBuffer nativeImageGetBuffer(int idx, int readerFormat);
         private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat);
+        private synchronized native int nativeGetWidth();
+        private synchronized native int nativeGetHeight();
     }
 
     private synchronized native void nativeInit(Object weakSelf, int w, int h,
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 4513643..6984575 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -126,6 +126,7 @@
                      new Rational(Integer.MAX_VALUE, 1));
     private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
     private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
+    private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
 
     // found stuff that is not supported by framework (=> this should not happen)
     private static final int ERROR_UNRECOGNIZED   = (1 << 0);
@@ -711,7 +712,7 @@
             }
             if (info.containsKey("bitrate-range")) {
                 bitRates = bitRates.intersect(
-                        Utils.parseIntRange(info.getString("bitrate"), bitRates));
+                        Utils.parseIntRange(info.getString("bitrate-range"), bitRates));
             }
             applyLimits(maxInputChannels, bitRates);
         }
@@ -1061,7 +1062,7 @@
         }
 
         private void initWithPlatformLimits() {
-            mBitrateRange = Range.create(0, Integer.MAX_VALUE);
+            mBitrateRange = BITRATE_RANGE;
 
             mWidthRange  = SIZE_RANGE;
             mHeightRange = SIZE_RANGE;
@@ -1090,7 +1091,7 @@
             Size blockSize = new Size(mBlockWidth, mBlockHeight);
             Size alignment = new Size(mWidthAlignment, mHeightAlignment);
             Range<Integer> counts = null, widths = null, heights = null;
-            Range<Integer> frameRates = null;
+            Range<Integer> frameRates = null, bitRates = null;
             Range<Long> blockRates = null;
             Range<Rational> ratios = null, blockRatios = null;
 
@@ -1148,6 +1149,16 @@
                     frameRates = null;
                 }
             }
+            bitRates = Utils.parseIntRange(map.get("bitrate-range"), null);
+            if (bitRates != null) {
+                try {
+                    bitRates = bitRates.intersect(BITRATE_RANGE);
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG,  "bitrate range (" + bitRates
+                            + ") is out of limits: " + BITRATE_RANGE);
+                    bitRates = null;
+                }
+            }
 
             checkPowerOfTwo(
                     blockSize.getWidth(), "block-size width must be power of two");
@@ -1196,6 +1207,9 @@
                 if (frameRates != null) {
                     mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
                 }
+                if (bitRates != null) {
+                    mBitrateRange = BITRATE_RANGE.intersect(bitRates);
+                }
             } else {
                 // no unsupported profile/levels, so restrict values to known limits
                 if (widths != null) {
@@ -1226,6 +1240,9 @@
                 if (frameRates != null) {
                     mFrameRateRange = mFrameRateRange.intersect(frameRates);
                 }
+                if (bitRates != null) {
+                    mBitrateRange = mBitrateRange.intersect(bitRates);
+                }
             }
             updateLimits();
         }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index acf1b43..615dac2 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -61,6 +61,7 @@
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -979,6 +980,9 @@
             // Redirect ringtones to go directly to underlying provider
             uri = RingtoneManager.getActualDefaultRingtoneUri(context,
                     RingtoneManager.getDefaultType(uri));
+            if (uri == null) {
+                throw new FileNotFoundException("Failed to resolve default ringtone");
+            }
         }
 
         AssetFileDescriptor fd = null;
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 7d075ba..8441541 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -51,6 +51,12 @@
 
     private final Context mContext;
     private final AudioManager mAudioManager;
+
+    /**
+     * Flag indicating if we're allowed to fall back to remote playback using
+     * {@link #mRemotePlayer}. Typically this is false when we're the remote
+     * player and there is nobody else to delegate to.
+     */
     private final boolean mAllowRemote;
     private final IRingtonePlayer mRemotePlayer;
     private final Binder mRemoteToken;
@@ -211,12 +217,7 @@
             mLocalPlayer.setAudioAttributes(mAudioAttributes);
             mLocalPlayer.prepare();
 
-        } catch (SecurityException e) {
-            destroyLocalPlayer();
-            if (!mAllowRemote) {
-                Log.w(TAG, "Remote playback not allowed: " + e);
-            }
-        } catch (IOException e) {
+        } catch (SecurityException | IOException e) {
             destroyLocalPlayer();
             if (!mAllowRemote) {
                 Log.w(TAG, "Remote playback not allowed: " + e);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index e13f008..df4bc78 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -412,7 +412,9 @@
      * @param metadata The new metadata
      */
     public void setMetadata(@Nullable MediaMetadata metadata) {
-        metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
+        if (metadata != null ) {
+            metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
+        }
         try {
             mBinder.setMetadata(metadata);
         } catch (RemoteException e) {
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 7830c80..3f4736d 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -615,6 +615,24 @@
     return rowStride;
 }
 
+static int Image_getBufferWidth(CpuConsumer::LockedBuffer* buffer) {
+    if (buffer == NULL) return -1;
+
+    if (!buffer->crop.isEmpty()) {
+        return buffer->crop.getWidth();
+    }
+    return buffer->width;
+}
+
+static int Image_getBufferHeight(CpuConsumer::LockedBuffer* buffer) {
+    if (buffer == NULL) return -1;
+
+    if (!buffer->crop.isEmpty()) {
+        return buffer->crop.getHeight();
+    }
+    return buffer->height;
+}
+
 // ----------------------------------------------------------------------------
 
 static void ImageReader_classInit(JNIEnv* env, jclass clazz)
@@ -795,33 +813,16 @@
     }
 
     // Check if the producer buffer configurations match what ImageReader configured.
-    // We want to fail for the very first image because this case is too bad.
-    int outputWidth = buffer->width;
-    int outputHeight = buffer->height;
-
-    // Correct width/height when crop is set.
-    if (!buffer->crop.isEmpty()) {
-        outputWidth = buffer->crop.getWidth();
-        outputHeight = buffer->crop.getHeight();
-    }
+    int outputWidth = Image_getBufferWidth(buffer);
+    int outputHeight = Image_getBufferHeight(buffer);
 
     int imgReaderFmt = ctx->getBufferFormat();
     int imageReaderWidth = ctx->getBufferWidth();
     int imageReaderHeight = ctx->getBufferHeight();
     if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (imgReaderFmt != HAL_PIXEL_FORMAT_BLOB) &&
-            (imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) {
-        /**
-         * For video decoder, the buffer height is actually the vertical stride,
-         * which is always >= actual image height. For future, decoder need provide
-         * right crop rectangle to CpuConsumer to indicate the actual image height,
-         * see bug 9563986. After this bug is fixed, we can enforce the height equal
-         * check. Right now, only make sure buffer height is no less than ImageReader
-         * height.
-         */
-        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                "Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
-                outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
-        return -1;
+            (imageReaderWidth != outputWidth || imageReaderHeight != outputHeight)) {
+        ALOGV("%s: Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
+                __FUNCTION__, outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
     }
 
     int bufFmt = buffer->format;
@@ -934,6 +935,19 @@
     return byteBuffer;
 }
 
+static jint Image_getWidth(JNIEnv* env, jobject thiz)
+{
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+    return Image_getBufferWidth(buffer);
+}
+
+static jint Image_getHeight(JNIEnv* env, jobject thiz)
+{
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+    return Image_getBufferHeight(buffer);
+}
+
+
 } // extern "C"
 
 // ----------------------------------------------------------------------------
@@ -943,14 +957,16 @@
     {"nativeInit",             "(Ljava/lang/Object;IIII)V",  (void*)ImageReader_init },
     {"nativeClose",            "()V",                        (void*)ImageReader_close },
     {"nativeReleaseImage",     "(Landroid/media/Image;)V",   (void*)ImageReader_imageRelease },
-    {"nativeImageSetup",       "(Landroid/media/Image;)I",    (void*)ImageReader_imageSetup },
+    {"nativeImageSetup",       "(Landroid/media/Image;)I",   (void*)ImageReader_imageSetup },
     {"nativeGetSurface",       "()Landroid/view/Surface;",   (void*)ImageReader_getSurface },
 };
 
 static JNINativeMethod gImageMethods[] = {
     {"nativeImageGetBuffer",   "(II)Ljava/nio/ByteBuffer;",   (void*)Image_getByteBuffer },
     {"nativeCreatePlane",      "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
-                                                             (void*)Image_createSurfacePlane },
+                                                              (void*)Image_createSurfacePlane },
+    {"nativeGetWidth",         "()I",                         (void*)Image_getWidth },
+    {"nativeGetHeight",        "()I",                         (void*)Image_getHeight },
 };
 
 int register_android_media_ImageReader(JNIEnv *env) {
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index b8acb45..06e8574 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -23,12 +23,10 @@
 import android.graphics.Bitmap;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Proxy;
-import android.net.ProxyInfo;
 import android.net.Uri;
 import android.net.http.SslError;
 import android.os.Bundle;
@@ -98,26 +96,10 @@
             done(CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS);
         }
 
+        final ConnectivityManager cm = ConnectivityManager.from(this);
         final Network network = new Network(mNetId);
-        ConnectivityManager.setProcessDefaultNetwork(network);
-
-        // Set HTTP proxy system properties to those of the selected Network.
-        final LinkProperties lp = ConnectivityManager.from(this).getLinkProperties(network);
-        if (lp != null) {
-            final ProxyInfo proxyInfo = lp.getHttpProxy();
-            String host = "";
-            String port = "";
-            String exclList = "";
-            Uri pacFileUrl = Uri.EMPTY;
-            if (proxyInfo != null) {
-                host = proxyInfo.getHost();
-                port = Integer.toString(proxyInfo.getPort());
-                exclList = proxyInfo.getExclusionListAsString();
-                pacFileUrl = proxyInfo.getPacFileUrl();
-            }
-            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
-            Log.v(TAG, "Set proxy system properties to " + proxyInfo);
-        }
+        // Also initializes proxy system properties.
+        cm.setProcessDefaultNetwork(network);
 
         // Proxy system properties must be initialized before setContentView is called because
         // setContentView initializes the WebView logic which in turn reads the system properties.
@@ -126,8 +108,7 @@
         getActionBar().setDisplayShowHomeEnabled(false);
 
         // Exit app if Network disappears.
-        final NetworkCapabilities networkCapabilities =
-                ConnectivityManager.from(this).getNetworkCapabilities(network);
+        final NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
         if (networkCapabilities == null) {
             finish();
             return;
@@ -142,7 +123,7 @@
         for (int transportType : networkCapabilities.getTransportTypes()) {
             builder.addTransportType(transportType);
         }
-        ConnectivityManager.from(this).registerNetworkCallback(builder.build(), mNetworkCallback);
+        cm.registerNetworkCallback(builder.build(), mNetworkCallback);
 
         final WebView myWebView = (WebView) findViewById(R.id.webview);
         myWebView.clearCache(true);
diff --git a/packages/Keyguard/res/values-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
index d5876b5..4bfd98e 100644
--- a/packages/Keyguard/res/values-af/strings.xml
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Wagwoord ontsluit."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Patroonarea."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sleep-area."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-area"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-PIN-area"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-PUK-area"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Vorigesnit-knoppie"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Volgendesnit-knoppie"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Laatwag-knoppie"</string>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index 07b8ba9..714a3eb 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"በይለፍ ቃል መክፈት።"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"የስርዓተ-ጥለት አካባቢ።"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"የማንሸራተቻ አካባቢ።"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"የፒን አካባቢ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"የሲም ፒን አካባቢ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"የሲም PUK አካባቢ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"የቀዳሚ ትራክ አዝራር"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"የቀጣይ ትራክ አዝራር"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ለአፍታ አቁም አዝራር"</string>
diff --git a/packages/Keyguard/res/values-bn-rBD/strings.xml b/packages/Keyguard/res/values-bn-rBD/strings.xml
index 00698f1..77acaf80 100644
--- a/packages/Keyguard/res/values-bn-rBD/strings.xml
+++ b/packages/Keyguard/res/values-bn-rBD/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"পাসওয়ার্ড দিয়ে আনলক৷"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"প্যাটার্ন এলাকা৷"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"স্লাইড করার এলাকা৷"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN অঞ্চল"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN অঞ্চল"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK অঞ্চল"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"পূর্ববর্তী ট্র্যাকে যাওয়ার বোতাম"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"পরবর্তী ট্র্যাকে যাওয়ার বোতাম"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"বিরাম বোতাম"</string>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index a83c944..ac745f1 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueig mitjançant contrasenya"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Àrea de patró"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar el dit"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Zona del PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Zona del PIN de la SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Zona del PUK de la SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botó de pista anterior"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botó de pista següent"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botó de pausa"</string>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
index ffc0abe..93b5756 100644
--- a/packages/Keyguard/res/values-da/strings.xml
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås op med adgangskode."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Strygeområde."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Område for pinkoden"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Område for pinkoden til simkortet"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Område for PUK-koden til simkortet"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knap til forrige nummer"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knap til næste nummer"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause-knap"</string>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
index ad77ab5..f6545a1 100644
--- a/packages/Keyguard/res/values-de/strings.xml
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Entsperrung mit Passwort"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bereich für Muster"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bereich für Fingerbewegung"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-Bereich"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-PIN-Bereich"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-PUK-Bereich"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Schaltfläche für vorherigen Titel"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Schaltfläche für nächsten Titel"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Schaltfläche für Pause"</string>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
index aa0d639..9dbe709 100644
--- a/packages/Keyguard/res/values-el/strings.xml
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ξεκλείδωμα κωδικού πρόσβασης."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Περιοχή μοτίβου."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Περιοχή ολίσθησης"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Περιοχή PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Περιοχή PIN SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Περιοχή PUK SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Κουμπί προηγούμενου κομματιού"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Κουμπί επόμενου κομματιού"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Κουμπί παύσης"</string>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
index 82417e4..6ac27be 100644
--- a/packages/Keyguard/res/values-en-rGB/strings.xml
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN area"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN area"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK area"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Previous track button"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Next track button"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause button"</string>
diff --git a/packages/Keyguard/res/values-en-rIN/strings.xml b/packages/Keyguard/res/values-en-rIN/strings.xml
index 82417e4..6ac27be 100644
--- a/packages/Keyguard/res/values-en-rIN/strings.xml
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN area"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN area"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK area"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Previous track button"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Next track button"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause button"</string>
diff --git a/packages/Keyguard/res/values-es-rUS/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
index 7d241b9..80058ba 100644
--- a/packages/Keyguard/res/values-es-rUS/strings.xml
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslizamiento"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área de PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área de PIN de SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área de PUK de SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botón de pista anterior"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botón de pista siguiente"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botón de pausa"</string>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
index 2f286a0..9d6cdc4 100644
--- a/packages/Keyguard/res/values-es/strings.xml
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área para deslizar"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área de PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área de PIN de SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área de PUK de SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botón de canción anterior"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botón de siguiente canción"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botón de pausa"</string>
diff --git a/packages/Keyguard/res/values-et-rEE/strings.xml b/packages/Keyguard/res/values-et-rEE/strings.xml
index 7902a28..ab953e1 100644
--- a/packages/Keyguard/res/values-et-rEE/strings.xml
+++ b/packages/Keyguard/res/values-et-rEE/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parooliga avamine."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mustri ala."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Lohistamisala."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-koodi ala"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-kaardi PIN-koodi ala"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-kaardi PUK-koodi ala"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Nupp Eelmine lugu"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nupp Järgmine lugu"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Nupp Peata"</string>
diff --git a/packages/Keyguard/res/values-eu-rES/strings.xml b/packages/Keyguard/res/values-eu-rES/strings.xml
index 7653777..ba2c931 100644
--- a/packages/Keyguard/res/values-eu-rES/strings.xml
+++ b/packages/Keyguard/res/values-eu-rES/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Pasahitzaren bidez desblokeatzea."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Eredua marrazteko eremua."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Hatza lerratzeko eremua."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN kodearen eremua"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM txartelaren PIN kodearen eremua"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM txartelaren PUK kodearen eremua"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Aurreko pistara joateko botoia"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Hurrengo pistara joateko botoia"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pausatzeko botoia"</string>
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
index b024285..fea1f59 100644
--- a/packages/Keyguard/res/values-fa/strings.xml
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"باز کردن قفل با گذرواژه."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ناحیه الگو."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ناحیه کشیدن انگشت روی صفحه."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"قسمت پین"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"قسمت پین سیم‌کارت"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"‏قسمت PUK سیم‌کارت"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"دکمه تراک قبلی"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"دکمه تراک بعدی"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"دکمه توقف موقت"</string>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
index a117a59..6cbc029 100644
--- a/packages/Keyguard/res/values-fi/strings.xml
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lukituksen poisto salasanalla."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kuvioalue."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Liu\'utusalue."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-koodin alue"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-kortin PIN-koodin alue"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-kortin PUK-koodin alue"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Edellinen kappale -painike"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Seuraava kappale -painike"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tauko-painike"</string>
diff --git a/packages/Keyguard/res/values-fr-rCA/strings.xml b/packages/Keyguard/res/values-fr-rCA/strings.xml
index 6771075..d5b62ee 100644
--- a/packages/Keyguard/res/values-fr-rCA/strings.xml
+++ b/packages/Keyguard/res/values-fr-rCA/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Zone du NIP"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Zone du NIP de la carte SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Zone du code PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Bouton pour revenir au titre précédent"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Bouton pour atteindre le titre suivant"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Bouton de pause"</string>
diff --git a/packages/Keyguard/res/values-fr/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
index 9900340..5a62057 100644
--- a/packages/Keyguard/res/values-fr/strings.xml
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Champ du code PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Champ du code PIN de la carte SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Champ du code PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Bouton pour revenir au titre précédent"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Bouton pour atteindre le titre suivant"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Bouton de pause"</string>
diff --git a/packages/Keyguard/res/values-gl-rES/strings.xml b/packages/Keyguard/res/values-gl-rES/strings.xml
index 8abb3ce..4cd8ae0 100644
--- a/packages/Keyguard/res/values-gl-rES/strings.xml
+++ b/packages/Keyguard/res/values-gl-rES/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo mediante contrasinal"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zona do padrón"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zona para pasar o dedo"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área do PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área do PIN da tarxeta SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área do PUK da tarxeta SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botón de pista anterior"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botón de pista seguinte"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botón de pausa"</string>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index a4d7237..c1f2b6c 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलॉक."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"आकार क्षेत्र."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"पिन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"सिम पिन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"सिम पिइउके क्षेत्र"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"पिछला ट्रैक बटन"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"अगला ट्रैक बटन"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"पॉज़ करें बटन"</string>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
index fcccddf..56c4bb1 100644
--- a/packages/Keyguard/res/values-hr/strings.xml
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Otključavanje zaporkom."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Područje uzorka."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Područje klizanja."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Područje PIN-a"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Područje PIN-a za SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Područje PUK-a za SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Gumb Prethodni zapis"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Gumb Sljedeći zapis"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Gumb Pauza"</string>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
index bb3d8a3..74a63bb 100644
--- a/packages/Keyguard/res/values-hu/strings.xml
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Feloldás jelszóval"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mintaterület"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Csúsztatási terület"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN kód területe"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN kód területe"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK kód területe"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Előző szám gomb"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Következő szám gomb"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Szünet gomb"</string>
diff --git a/packages/Keyguard/res/values-hy-rAM/strings.xml b/packages/Keyguard/res/values-hy-rAM/strings.xml
index d945c74..e233d12 100644
--- a/packages/Keyguard/res/values-hy-rAM/strings.xml
+++ b/packages/Keyguard/res/values-hy-rAM/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Գաղտնաբառի ապակողպում:"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Սխեմայի տարածք:"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Սահեցման տարածք:"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN կոդի տարածք"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM քարտի PIN կոդի տարածք"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM քարտի PUK կոդի տարածք"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Նախորդ հետագծի կոճակը"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Հաջորդ հետագծի կոճակը"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Դադարի կոճակ"</string>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
index fcac080..d637208 100644
--- a/packages/Keyguard/res/values-in/strings.xml
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci dengan sandi."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area pola."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area geser."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Bidang PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Bidang PIN SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Bidang PUK SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Tombol lagu sebelumnya"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Tombol lagu berikutnya"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tombol jeda"</string>
diff --git a/packages/Keyguard/res/values-is-rIS/strings.xml b/packages/Keyguard/res/values-is-rIS/strings.xml
index 9f4798b..d1d8dc2 100644
--- a/packages/Keyguard/res/values-is-rIS/strings.xml
+++ b/packages/Keyguard/res/values-is-rIS/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Opnun með aðgangsorði."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Svæði mynsturs."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Stroksvæði."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-svæði"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"PIN-svæði SIM-korts"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"PUK-svæði SIM-korts"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Hnappur fyrir fyrra lag"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Hnappur fyrir næsta lag"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Hnappur til að gera hlé"</string>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
index ccfc855..ac7de84 100644
--- a/packages/Keyguard/res/values-it/strings.xml
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Sblocco con password."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area sequenza."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area di scorrimento."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Area PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Area PIN SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Area PUK SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Pulsante traccia precedente"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Pulsante traccia successiva"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pulsante Pausa"</string>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index b05de86..2d8f1bf 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ביטול נעילה באמצעות סיסמה."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"אזור ציור קו."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"אזור הסטה."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"‏אזור עבור קוד PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"‏אזור עבור קוד PIN של SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"‏אזור עבור קוד PUK של SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"לחצן \'הרצועה הקודמת\'"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"לחצן \'הרצועה הבאה\'"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"לחצן \'השהה\'"</string>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index ba66413..39dc52e 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"パスワードロックを解除します。"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"パターンエリアです。"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"スライドエリアです。"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PINエリア"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PINエリア"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUKエリア"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"前のトラックボタン"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"次のトラックボタン"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"一時停止ボタン"</string>
diff --git a/packages/Keyguard/res/values-ka-rGE/strings.xml b/packages/Keyguard/res/values-ka-rGE/strings.xml
index 0845a0b..ccd6bea 100644
--- a/packages/Keyguard/res/values-ka-rGE/strings.xml
+++ b/packages/Keyguard/res/values-ka-rGE/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"პაროლის განბლოკვა"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ნიმუშების სივრცე."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"გადასრიალების სივრცე."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-ის არე"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-ის PIN-ის არე"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-ის PUK-ის არე"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"წინა ჩანაწერის ღილაკი"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"შემდეგი ჩანაწერის ღილაკი"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"პაუზის ღილაკი"</string>
diff --git a/packages/Keyguard/res/values-kk-rKZ/strings.xml b/packages/Keyguard/res/values-kk-rKZ/strings.xml
index fff5b4d..1663ca0 100644
--- a/packages/Keyguard/res/values-kk-rKZ/strings.xml
+++ b/packages/Keyguard/res/values-kk-rKZ/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Кілтсөз арқылы ашу."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Кескін арқылы ашу аймағы."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Сырғыту аймағы."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN аумағы"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN аумағы"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK аумағы"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Алдыңғы жол түймесі"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Келесі жол түймесі"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кідірту түймесі"</string>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index ca95c82..f4a73a8 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ពាក្យ​សម្ងាត់​ដោះ​សោ​។"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ផ្ទៃ​លំនាំ។"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ផ្ទៃ​រុញ។"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"ប្រអប់លេខសម្ងាត់"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"ប្រអប់លេខសម្ងាត់ស៊ីម"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"ប្រអប់ PUK ស៊ីម"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ប៊ូតុង​បទ​មុន"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ប៊ូតុង​បទ​បន្ទាប់"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ប៊ូតុង​ផ្អាក"</string>
diff --git a/packages/Keyguard/res/values-kn-rIN/strings.xml b/packages/Keyguard/res/values-kn-rIN/strings.xml
index 8cc2886..6e2b4d0 100644
--- a/packages/Keyguard/res/values-kn-rIN/strings.xml
+++ b/packages/Keyguard/res/values-kn-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್‌ಲಾಕ್."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ನಮೂನೆ ಪ್ರದೇಶ."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ಸ್ಲೈಡ್ ಪ್ರದೇಶ."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"ಪಿನ್ ಪ್ರದೇಶ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"ಸಿಮ್ ಪಿನ್ ಪ್ರದೇಶ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"ಸಿಮ್ PUK ಪ್ರದೇಶ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ಹಿಂದಿನ ಹಾಡಿನ ಬಟನ್"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ಮುಂದಿನ ಹಾಡಿನ ಬಟನ್"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ವಿರಾಮ ಬಟನ್"</string>
diff --git a/packages/Keyguard/res/values-ko/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
index 973ebaa..b60b159 100644
--- a/packages/Keyguard/res/values-ko/strings.xml
+++ b/packages/Keyguard/res/values-ko/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"비밀번호를 사용하여 잠금해제합니다."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"패턴을 그리는 부분입니다."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"슬라이드하는 부분입니다."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN 영역"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN 영역"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK 영역"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"이전 트랙 버튼"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"다음 트랙 버튼"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"일시중지 버튼"</string>
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 7fa8762..f90acb4 100644
--- a/packages/Keyguard/res/values-ky-rKG/strings.xml
+++ b/packages/Keyguard/res/values-ky-rKG/strings.xml
@@ -67,12 +67,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Сырсөз менен ачуу."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Үлгү аймагы."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Жылмыштыруу аймагы."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN аймагы"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN аймагы"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK аймагы"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Мурунку трек баскычы"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кийинки трек баскычы"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Тыныгуу баскычы"</string>
diff --git a/packages/Keyguard/res/values-lo-rLA/strings.xml b/packages/Keyguard/res/values-lo-rLA/strings.xml
index 39d53dc..40f1893 100644
--- a/packages/Keyguard/res/values-lo-rLA/strings.xml
+++ b/packages/Keyguard/res/values-lo-rLA/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ການປົດລັອກດ້ວຍລະຫັດຜ່ານ."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ພື້ນທີ່ຮູບແບບ."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ເລື່ອນພື້ນທີ່."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"ພື້ນ​ທີ່ PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"ພື້ນ​ທີ່ PIN ຂອງ SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"ພື້ນ​ທີ່ PUK ຂອງ SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ປຸ່ມເພງກ່ອນໜ້າ"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ປຸ່ມເພງຕໍ່ໄປ"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
diff --git a/packages/Keyguard/res/values-lt/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
index 3ccf5b9..eb9c910 100644
--- a/packages/Keyguard/res/values-lt/strings.xml
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Atrakinimas įvedus slaptažodį."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Atrakinimo pagal piešinį sritis."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slydimo sritis."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN kodo sritis"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM kortelės PIN kodo sritis"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM kortelės PUK kodo sritis"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Ankstesnio takelio mygtukas"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Kito takelio mygtukas"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pristabdymo mygtukas"</string>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
index 35a1664..920a141 100644
--- a/packages/Keyguard/res/values-lv/strings.xml
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Autorizācija ar paroli."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kombinācijas ievades apgabals."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Apgabals, kur vilkt ar pirkstu."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN apgabals"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN apgabals"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK apgabals"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Iepriekšējā ieraksta poga"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nākamā ieraksta poga"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pārtraukšanas poga"</string>
diff --git a/packages/Keyguard/res/values-mk-rMK/strings.xml b/packages/Keyguard/res/values-mk-rMK/strings.xml
index 87589b98..a94503b 100644
--- a/packages/Keyguard/res/values-mk-rMK/strings.xml
+++ b/packages/Keyguard/res/values-mk-rMK/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Отклучување со лозинка."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Област за шема."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Област за лизгање."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Поле за ПИН"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Поле за ПИН на СИМ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Поле за ПУК на СИМ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Копче „Претходна песна“"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Копче „Следна песна“"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Копче „Пауза“"</string>
diff --git a/packages/Keyguard/res/values-ml-rIN/strings.xml b/packages/Keyguard/res/values-ml-rIN/strings.xml
index ad36036..20c73a3 100644
--- a/packages/Keyguard/res/values-ml-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ml-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"പാസ്‌വേഡ് അൺലോക്ക്."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"പാറ്റേൺ ഏരിയ."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"സ്ലൈഡ് ഏരിയ."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN ഏരിയ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN ഏരിയ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK ഏരിയ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"മുമ്പത്തെ ട്രാക്ക് ബട്ടൺ"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"പുതിയ ട്രാക്ക് ബട്ടൺ"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"താൽക്കാലികമായി നിർത്തുക ബട്ടൺ"</string>
diff --git a/packages/Keyguard/res/values-mn-rMN/strings.xml b/packages/Keyguard/res/values-mn-rMN/strings.xml
index 504b890..f2d6f8c 100644
--- a/packages/Keyguard/res/values-mn-rMN/strings.xml
+++ b/packages/Keyguard/res/values-mn-rMN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Тайлах нууц үг."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Хээний хэсэг."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Гулсуулах хэсэг."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN талбар"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN талбар"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK талбар"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Өмнөх бичлэг товч"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Дараагийн бичлэг товч"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Түр зогсоох товч"</string>
diff --git a/packages/Keyguard/res/values-mr-rIN/strings.xml b/packages/Keyguard/res/values-mr-rIN/strings.xml
index ab3f2a5..47b6ebb 100644
--- a/packages/Keyguard/res/values-mr-rIN/strings.xml
+++ b/packages/Keyguard/res/values-mr-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"संकेतशब्द अनलॉक."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"नमुना क्षेत्र."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"पिन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"सिम पिन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"सिम PUK क्षेत्र"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"मागील ट्रॅक बटण"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"पुढील ट्रॅक बटण"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"विराम बटण"</string>
diff --git a/packages/Keyguard/res/values-ms-rMY/strings.xml b/packages/Keyguard/res/values-ms-rMY/strings.xml
index 55f2177..8f46081 100644
--- a/packages/Keyguard/res/values-ms-rMY/strings.xml
+++ b/packages/Keyguard/res/values-ms-rMY/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci kata laluan."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kawasan corak."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kawasan luncur."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Kawasan PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Kawasan PIN SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Kawasan PUK SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Butang lagu sebelumnya"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Butang lagu seterusnya"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Butang jeda"</string>
diff --git a/packages/Keyguard/res/values-my-rMM/strings.xml b/packages/Keyguard/res/values-my-rMM/strings.xml
index 047b5d6..a7ba0e5 100644
--- a/packages/Keyguard/res/values-my-rMM/strings.xml
+++ b/packages/Keyguard/res/values-my-rMM/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"စကားဝှက်ဖြင့် သော့ဖွင့်ခြင်း"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ပုံစံနေရာ"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ဘေးတိုက်ပွတ်ဆွဲရန် နေရာ"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN နေရာ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN နေရာ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK နေရာ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ပြီးခဲ့သော အပုဒ်အတွက် ခလုတ်"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"နောက်တစ်ပုဒ် ခလုတ်"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ခဏရပ်ရန် ခလုတ်"</string>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
index 4d6e82b..0f7fa66 100644
--- a/packages/Keyguard/res/values-nb/strings.xml
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Passordopplåsning."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Dra-felt."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-området"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"PIN-området for SIM-kortet"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"PUK-området for SIM-kortet"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Forrige spor-knapp"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Neste spor-knapp"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause-knapp"</string>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
index 36e3732..00b9ece 100644
--- a/packages/Keyguard/res/values-ne-rNP/strings.xml
+++ b/packages/Keyguard/res/values-ne-rNP/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलक।"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ढाँचा क्षेत्र।"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र।"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"पीन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM पिन क्षेत्र"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM पुक क्षेत्र"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"अघिल्लो पथ बटन"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"अर्को पथ बटन"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"रोक्ने बटन"</string>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
index ed40563..518a1e1 100644
--- a/packages/Keyguard/res/values-nl/strings.xml
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ontgrendeling via wachtwoord."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Tekengebied voor patroon."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Schuifgebied."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Gebied voor pincode"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Gebied voor sim-pincode"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Gebied voor sim-pukcode"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knop voor vorig nummer"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knop voor volgend nummer"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Knop voor onderbreken"</string>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
index 3c03149..623c8ca 100644
--- a/packages/Keyguard/res/values-pl/strings.xml
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odblokowanie hasłem."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Obszar wzoru."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Obszar przesuwania."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Miejsce na PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Miejsce na PIN do karty SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Miejsce na PUK do karty SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Przycisk poprzedniego utworu"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Przycisk następnego utworu"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Przycisk wstrzymania"</string>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
index cce43ff..0556812 100644
--- a/packages/Keyguard/res/values-pt-rPT/strings.xml
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio através de palavra-passe."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área da sequência."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área do PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área do PIN do SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área do PUK do SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botão Faixa anterior"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botão Faixa seguinte"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botão Pausa"</string>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
index c41ec80..154eaa7 100644
--- a/packages/Keyguard/res/values-pt/strings.xml
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio com senha."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área do padrão."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área do PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área do PIN SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área do PUK SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botão \"Faixa anterior\""</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botão \"Próxima faixa\""</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botão \"Pausar\""</string>
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
index f1db847..dd3fe2f 100644
--- a/packages/Keyguard/res/values-ro/strings.xml
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Deblocare cu parolă."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zonă model."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zonă glisare."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Zona codului PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Zona codului PIN al cardului SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Zona codului PUK al cardului SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Butonul Melodia anterioară"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Butonul Melodia următoare"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Butonul Întrerupeți"</string>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
index 23addcc..1edfba5 100644
--- a/packages/Keyguard/res/values-ru/strings.xml
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Пароль"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Область ввода графического ключа"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Область слайдера"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-код"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"PIN-код SIM-карты"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"PUK-код SIM-карты"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Кнопка перехода к предыдущему треку"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кнопка перехода к следующему треку"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кнопка паузы"</string>
diff --git a/packages/Keyguard/res/values-si-rLK/strings.xml b/packages/Keyguard/res/values-si-rLK/strings.xml
index fb3fcd9..6527874 100644
--- a/packages/Keyguard/res/values-si-rLK/strings.xml
+++ b/packages/Keyguard/res/values-si-rLK/strings.xml
@@ -68,12 +68,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"මුරපද අගුළු ඇරීම."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"රටා ප්‍රදේශය."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"සර්පණ ප්‍රදේශය."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN කොටස"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN කොටස"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK කොටස"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"පෙර ගීත බොත්තම"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ඉදිරි ගීත බොත්තම"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"විරාම බොත්තම"</string>
diff --git a/packages/Keyguard/res/values-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
index f680891..c8c05f2 100644
--- a/packages/Keyguard/res/values-sk/strings.xml
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odomknutie heslom."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblasť na zadanie bezpečnostného vzoru."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblasť na prejdenie prstom."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Oblasť kódu PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Oblasť kódu PIN SIM karty"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Oblasť kódu PUK SIM karty"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Tlačidlo Predchádzajúca stopa"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Tlačidlo Ďalšia stopa"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tlačidlo Pozastaviť"</string>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
index c0d2ec2..d7ae794 100644
--- a/packages/Keyguard/res/values-sr/strings.xml
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Откључавање лозинком."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Област шаблона."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Област превлачења."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Област за PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Област за PIN за SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Област за PUK за SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Дугме за претходну песму"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Дугме за следећу песму"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Дугме за паузу"</string>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
index db2a2e0..a86b489 100644
--- a/packages/Keyguard/res/values-sv/strings.xml
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås upp med lösenord."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Fält för grafiskt lösenord."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Fält med dragreglage."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Pinkodsområde"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Pinkodsområde för SIM-kort"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"PUK-kodsområde för SIM-kort"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knapp för föregående spår"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knapp för nästa spår"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pausknappen"</string>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
index 8150313..2e67ff7 100644
--- a/packages/Keyguard/res/values-sw/strings.xml
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Kufungua kwa nenosiri."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Eneo la ruwaza."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Eneo la slaidi."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Eneo la PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Eneo la PIN ya SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Eneo la PUK ya SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Kitufe cha wimbo uliotangulia"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Kitufe cha wimbo unaofuata"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Kitufe cha kusitisha"</string>
diff --git a/packages/Keyguard/res/values-ta-rIN/strings.xml b/packages/Keyguard/res/values-ta-rIN/strings.xml
index e03baa0..19a02b9 100644
--- a/packages/Keyguard/res/values-ta-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ta-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"கடவுச்சொல் மூலம் திறத்தல்."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"வடிவப் பகுதி."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ஸ்லைடு பகுதி."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN பகுதி"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"சிம் PIN பகுதி"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"சிம் PUK பகுதி"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"முந்தைய டிராக்கிற்கான பொத்தான்"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"அடுத்த டிராக்கிற்கான பொத்தான்"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"இடைநிறுத்த பொத்தான்"</string>
diff --git a/packages/Keyguard/res/values-te-rIN/strings.xml b/packages/Keyguard/res/values-te-rIN/strings.xml
index a2b162a..30173b0 100644
--- a/packages/Keyguard/res/values-te-rIN/strings.xml
+++ b/packages/Keyguard/res/values-te-rIN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"పాస్‌వర్డ్ అన్‌లాక్."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"నమూనా ప్రాంతం."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"స్లయిడ్ ప్రాంతం."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN ప్రాంతం"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN ప్రాంతం"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK ప్రాంతం"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"మునుపటి ట్రాక్ బటన్"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"తదుపరి ట్రాక్ బటన్"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"పాజ్ బటన్"</string>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
index 8fe73fd..1d7bc66 100644
--- a/packages/Keyguard/res/values-th/strings.xml
+++ b/packages/Keyguard/res/values-th/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"การปลดล็อกด้วยรหัสผ่าน"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"พื้นที่สำหรับรูปแบบ"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"พื้นที่สำหรับการเลื่อน"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"พื้นที่ PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"พื้นที่ PIN ของซิม"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"พื้นที่ PUK ของซิม"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ปุ่มแทร็กก่อนหน้า"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ปุ่มแทร็กถัดไป"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ปุ่มหยุดชั่วคราว"</string>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
index 95bdb43..fb03d07 100644
--- a/packages/Keyguard/res/values-tl/strings.xml
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Pag-unlock ng password."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bahagi ng pattern."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bahagi ng slide."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Lugar ng PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Lugar ng PIN ng SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Lugar ng PUK ng SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Button na Nakaraang track"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Button na Susunod na track"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Button na I-pause"</string>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
index 4ada6a5..3bc4860 100644
--- a/packages/Keyguard/res/values-tr/strings.xml
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifreyle kilit açma."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Desen alanı."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kaydırma alanı."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN alanı"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN alanı"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK alanı"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Önceki parça düğmesi"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Sonraki parça düğmesi"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Duraklat düğmesi"</string>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
index a77f9d0f..3cb0b89 100644
--- a/packages/Keyguard/res/values-uk/strings.xml
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Розблокування паролем."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Область ключа."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Область повзунка."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-код"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"PIN-код SIM-карти"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"PUK-код SIM-карти"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Кнопка \"Попередня композиція\""</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кнопка \"Наступна композиція\""</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кнопка \"Призупинити\""</string>
diff --git a/packages/Keyguard/res/values-ur-rPK/strings.xml b/packages/Keyguard/res/values-ur-rPK/strings.xml
index 342466e..f4e4eeb 100644
--- a/packages/Keyguard/res/values-ur-rPK/strings.xml
+++ b/packages/Keyguard/res/values-ur-rPK/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"پاس ورڈ کے ذریعہ غیر مقفل کریں۔"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"پیٹرن کا علاقہ۔"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"سلائیڈ کرنے کا علاقہ۔"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"‏PIN کا علاقہ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"‏SIM PIN کا علاقہ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"‏SIM PUK کا علاقہ"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"سابقہ ٹریک بٹن"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"اگلا ٹریک بٹن"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"موقوف کرنے کا بٹن"</string>
diff --git a/packages/Keyguard/res/values-uz-rUZ/strings.xml b/packages/Keyguard/res/values-uz-rUZ/strings.xml
index 2faf1ee..cc891b2 100644
--- a/packages/Keyguard/res/values-uz-rUZ/strings.xml
+++ b/packages/Keyguard/res/values-uz-rUZ/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parolli qulfni ochish."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Chizmali qulf maydoni."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Maydonni silang"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN kod maydoni"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM karta PIN kodi maydoni"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM karta PUK kodi maydoni"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Avvalgi qo‘shiq tugmasi"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Keyingi qo‘shiq tugmasi"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza tugmasi"</string>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
index 58ac06a..0190f1c 100644
--- a/packages/Keyguard/res/values-vi/strings.xml
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Mở khóa bằng mật khẩu."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Khu vực hình."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Khu vực trượt."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Khu vực mã PIN"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Khu vực mã PIN của SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Khu vực PUK của SIM"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Nút bản nhạc trước"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nút bản nhạc tiếp theo"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Nút tạm dừng"</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 6890858..449cc1e 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密码解锁。"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"图案区域。"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑动区域。"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN 码区域"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM 卡 PIN 码区域"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM 卡 PUK 码区域"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"上一曲按钮"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"下一曲按钮"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"暂停按钮"</string>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
index 1eb69e9..be19441 100644
--- a/packages/Keyguard/res/values-zh-rHK/strings.xml
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密碼解鎖。"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"圖案區域。"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑動區域。"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN 區域"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM PIN 區域"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK 區域"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"[上一首曲目] 按鈕"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"[下一首曲目] 按鈕"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"[暫停] 按鈕"</string>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
index 19f0a56..82ef9d1 100644
--- a/packages/Keyguard/res/values-zh-rTW/strings.xml
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密碼解鎖。"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"圖形區域。"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑動區域。"</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN 區"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM 卡 PIN 區"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM 卡 PUK 區"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"[上一首曲目] 按鈕"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"[下一首曲目] 按鈕"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"[暫停] 按鈕"</string>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index b75bd18..f8c8f53 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -66,12 +66,9 @@
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ukuvula ngephasiwedi."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Indawo yephethini."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Indawo yokushelelisa."</string>
-    <!-- no translation found for keyguard_accessibility_pin_area (7903959476607833485) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_pin_area (3887780775111719336) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_sim_puk_area (1880823406954996207) -->
-    <skip />
+    <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Indawo yephinikhodi"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Indawo yephinikhodi ye-SIM"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Indawo ye-SIM PUK"</string>
     <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Inkinombo yethrekhi yangaphambilini"</string>
     <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Inkinobho yethrekhi elandelayo"</string>
     <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Inkinobho yokumiswa isikhashana"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
index 7f4ce59..d8b0c71 100644
--- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -21,6 +21,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.net.ConnectivityManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
@@ -140,14 +141,23 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
-        mKeyguardUpdateMonitor.registerCallback(mCallback);
+        if (ConnectivityManager.from(mContext).isNetworkSupported(
+                ConnectivityManager.TYPE_MOBILE)) {
+            mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+            mKeyguardUpdateMonitor.registerCallback(mCallback);
+        } else {
+            // Don't listen and clear out the text when the device isn't a phone.
+            mKeyguardUpdateMonitor = null;
+            setText("");
+        }
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        mKeyguardUpdateMonitor.removeCallback(mCallback);
+        if (mKeyguardUpdateMonitor != null) {
+            mKeyguardUpdateMonitor.removeCallback(mCallback);
+        }
     }
 
     /**
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 3212eec..0dfe1dc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -370,6 +370,7 @@
             final Runnable finishListener) {
         if (appearing) {
             animatedCell.scale = 0.0f;
+            animatedCell.alpha = 1.0f;
         }
         animatedCell.translateY = appearing ? translationY : 0;
         ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY,
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index bca0305..7c56e84 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -17,7 +17,11 @@
 package com.android.keyguard;
 
 import android.content.Context;
+import android.database.ContentObserver;
 import android.graphics.Rect;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.View;
@@ -28,19 +32,39 @@
 public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
         implements View.OnKeyListener {
 
+    private final android.database.ContentObserver mSpeakPasswordObserver
+            = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            // Ensure that it's not called too early
+            if (mButton0 != null) {
+                mButton0.updateContentDescription();
+                mButton1.updateContentDescription();
+                mButton2.updateContentDescription();
+                mButton3.updateContentDescription();
+                mButton4.updateContentDescription();
+                mButton5.updateContentDescription();
+                mButton6.updateContentDescription();
+                mButton7.updateContentDescription();
+                mButton8.updateContentDescription();
+                mButton9.updateContentDescription();
+            }
+        }
+    };
     protected PasswordTextView mPasswordEntry;
     private View mOkButton;
     private View mDeleteButton;
-    private View mButton0;
-    private View mButton1;
-    private View mButton2;
-    private View mButton3;
-    private View mButton4;
-    private View mButton5;
-    private View mButton6;
-    private View mButton7;
-    private View mButton8;
-    private View mButton9;
+    private NumPadKey mButton0;
+    private NumPadKey mButton1;
+    private NumPadKey mButton2;
+    private NumPadKey mButton3;
+    private NumPadKey mButton4;
+    private NumPadKey mButton5;
+    private NumPadKey mButton6;
+    private NumPadKey mButton7;
+    private NumPadKey mButton8;
+    private NumPadKey mButton9;
 
     public KeyguardPinBasedInputView(Context context) {
         this(context, null);
@@ -48,6 +72,9 @@
 
     public KeyguardPinBasedInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        context.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD), true,
+                mSpeakPasswordObserver, UserHandle.USER_ALL);
     }
 
     @Override
@@ -188,16 +215,16 @@
             }
         });
 
-        mButton0 = findViewById(R.id.key0);
-        mButton1 = findViewById(R.id.key1);
-        mButton2 = findViewById(R.id.key2);
-        mButton3 = findViewById(R.id.key3);
-        mButton4 = findViewById(R.id.key4);
-        mButton5 = findViewById(R.id.key5);
-        mButton6 = findViewById(R.id.key6);
-        mButton7 = findViewById(R.id.key7);
-        mButton8 = findViewById(R.id.key8);
-        mButton9 = findViewById(R.id.key9);
+        mButton0 = (NumPadKey) findViewById(R.id.key0);
+        mButton1 = (NumPadKey) findViewById(R.id.key1);
+        mButton2 = (NumPadKey) findViewById(R.id.key2);
+        mButton3 = (NumPadKey) findViewById(R.id.key3);
+        mButton4 = (NumPadKey) findViewById(R.id.key4);
+        mButton5 = (NumPadKey) findViewById(R.id.key5);
+        mButton6 = (NumPadKey) findViewById(R.id.key6);
+        mButton7 = (NumPadKey) findViewById(R.id.key7);
+        mButton8 = (NumPadKey) findViewById(R.id.key8);
+        mButton9 = (NumPadKey) findViewById(R.id.key9);
 
         mPasswordEntry.requestFocus();
         super.onFinishInflate();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 5350e5a..1e2a233 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -81,11 +81,11 @@
     SecurityMode getSecurityMode() {
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
         SecurityMode mode = SecurityMode.None;
-        if (monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED)
-                != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+        if (SubscriptionManager.isValidSubscriptionId(
+                monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) {
             mode = SecurityMode.SimPin;
-        } else if (monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED)
-                != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+        } else if (SubscriptionManager.isValidSubscriptionId(
+                    monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED))
                 && mLockPatternUtils.isPukUnlockScreenEnable()) {
             mode = SecurityMode.SimPuk;
         } else {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index f1c4cd4..f4acff8 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -75,7 +75,7 @@
         if (DEBUG) Log.v(TAG, "Resetting state");
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
         mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
-        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
             int count = TelephonyManager.getDefault().getSimCount();
             Resources rez = getResources();
             final String msg;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index c9670bb..b85d966 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -118,7 +118,7 @@
             state = ENTER_PUK;
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
-            if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
                 int count = TelephonyManager.getDefault().getSimCount();
                 Resources rez = getResources();
                 final String msg;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 8458ae0..c8cfe31 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -938,7 +938,7 @@
                     + slotId + ", state=" + state +")");
         }
 
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             Log.w(TAG, "invalid subId in handleSimStateChange()");
             return;
         }
diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
index d539856..70a4108 100644
--- a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
+++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
@@ -22,6 +22,8 @@
 import android.os.Debug;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
@@ -118,7 +120,17 @@
         }
 
         setBackground(mContext.getDrawable(R.drawable.ripple_drawable));
-        setContentDescription(mDigitText.getText().toString() + mKlondikeText.getText().toString());
+        updateContentDescription();
+    }
+
+    public void updateContentDescription() {
+        if (shouldSpeakPasswordsForAccessibility()) {
+            setContentDescription(
+                    mDigitText.getText().toString() + mKlondikeText.getText().toString());
+        } else {
+            setContentDescription(getContext().getString(
+                    com.android.internal.R.string.keyboard_password_character_no_headset));
+        }
     }
 
     @Override
@@ -152,6 +164,15 @@
         mKlondikeText.layout(left, top, left + mKlondikeText.getMeasuredWidth(), bottom);
     }
 
+    /**
+     * @return true if the user has explicitly allowed accessibility services
+     * to speak passwords.
+     */
+    private boolean shouldSpeakPasswordsForAccessibility() {
+        return (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0, UserHandle.USER_CURRENT) == 1);
+    }
+
     @Override
     public boolean hasOverlappingRendering() {
         return false;
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0e69f74..b606a6f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -197,6 +197,7 @@
         <!-- Alternate Recents -->
         <activity android:name=".recents.RecentsActivity"
                   android:label="@string/accessibility_desc_recent_apps"
+                  android:exported="false"
                   android:launchMode="singleInstance"
                   android:excludeFromRecents="true"
                   android:stateNotNeeded="true"
@@ -207,6 +208,17 @@
             </intent-filter>
         </activity>
 
+        <receiver android:name=".recents.RecentsUserEventProxyReceiver"
+                  android:exported="false">
+            <intent-filter>
+                <action android:name="com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER" />
+                <action android:name="com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER" />
+                <action android:name="com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER" />
+                <action android:name="com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER" />
+                <action android:name="com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER" />
+            </intent-filter>
+        </receiver>
+
         <!-- started from UsbDeviceSettingsManager -->
         <activity android:name=".usb.UsbConfirmActivity"
             android:exported="true"
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index ca07c87..4cf4f52d 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -29,6 +29,7 @@
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
         android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal"
         android:textStyle="italic"
         android:textColor="#ffffff"
         android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index 48bb213..5a96dc3 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -14,7 +14,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.keyguard.AlphaOptimizedLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentBottom="true"
@@ -36,4 +37,4 @@
         android:clickable="false"
         android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
 
-</LinearLayout>
\ No newline at end of file
+</com.android.keyguard.AlphaOptimizedLinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_detail_items.xml b/packages/SystemUI/res/layout/qs_detail_items.xml
index f61a43c..c22e42c 100644
--- a/packages/SystemUI/res/layout/qs_detail_items.xml
+++ b/packages/SystemUI/res/layout/qs_detail_items.xml
@@ -49,4 +49,8 @@
             android:textAppearance="@style/TextAppearance.QS.DetailEmpty" />
     </LinearLayout>
 
+    <View
+        android:id="@+id/min_height_spacer"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"/>
 </com.android.systemui.qs.QSDetailItems>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index c76d442..1873168 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
+<com.android.systemui.qs.QSContainer
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/quick_settings_container"
         android:layout_width="match_parent"
@@ -28,4 +28,4 @@
             android:background="#0000"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
-</FrameLayout>
+</com.android.systemui.qs.QSContainer>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 2fb7cdbf..f717ac7 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -154,7 +154,7 @@
         android:layout_alignParentBottom="true"
         />
 
-    <ImageView
+    <com.android.systemui.statusbar.AlphaOptimizedImageView
         android:id="@+id/qs_detail_header_progress"
         android:src="@drawable/indeterminate_anim"
         android:alpha="0"
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index e1cd73a0..f61724d 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -266,7 +266,7 @@
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
-    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torch"</string>
     <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobile data"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index e1cd73a0..f61724d 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -266,7 +266,7 @@
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
-    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torch"</string>
     <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobile data"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 7c0064e..fc5b18c 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Süsteemi UI"</string>
-    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Kustuta"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Tühjenda"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Loendist eemaldamine"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Rakenduse teave"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Teie viimane ekraanikuva ilmub siia"</string>
@@ -31,7 +31,7 @@
   </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Teatisi pole"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Jätkuv"</string>
-    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Teadistused"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Märguanded"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"Aku hakkab tühjaks saama"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"Jäänud on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Jäänud on <xliff:g id="PERCENTAGE">%s</xliff:g>. Akusäästja on sisse lülitatud."</string>
@@ -149,7 +149,7 @@
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Aku: <xliff:g id="NUMBER">%d</xliff:g> protsenti."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Süsteemiseaded"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Teatised"</string>
-    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Teatise kustutamine"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Märguande eemaldamine."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS on lubatud."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-signaali otsimine."</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter lubatud."</string>
diff --git a/packages/SystemUI/res/values-h560dp/config.xml b/packages/SystemUI/res/values-h560dp/config.xml
new file mode 100644
index 0000000..f210d7b
--- /dev/null
+++ b/packages/SystemUI/res/values-h560dp/config.xml
@@ -0,0 +1,23 @@
+<?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>
+    <!-- The maximum number of items to be displayed in quick settings -->
+    <integer name="quick_settings_detail_max_item_count">8</integer>
+</resources>
+
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 90b62bf..d581e73 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -318,8 +318,8 @@
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"削除"</string>
     <string name="guest_wipe_session_title" msgid="6419439912885956132">"おかえりなさい、ゲストさん"</string>
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"セッションを続行しますか?"</string>
-    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"最初から再生"</string>
-    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"次へ進む"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"最初から開始"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"続行"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"新しいユーザーを追加しますか?"</string>
     <string name="user_add_user_message_short" msgid="2161624834066214559">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"バッテリーセーバーがON"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index f17a524..9808830 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -355,8 +355,8 @@
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ຕັ້ງຄ່າ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ປັກ​ໝຸດໜ້າ​ຈໍ​ແລ້ວ"</string>
-    <string name="screen_pinning_description" msgid="1346522416878235405">"ມັນ​ຈະ​ຮັກ​ສາ​ໜ້າ​ຈໍ​ໄວ້​ໃນ​ມຸມມອງ​ຂອງ​ທ່ານ​ຈົນ​ກວ່າ​ທ່ານ​ຈະ​ຖອດ​ໝຸດ. ​ສຳ​ຜັດ​ປຸ່ມ ກັບ​ຄືນ ແລະ ພາບ​ຮວມ​ ຄ້າງ​ໄວ້​ພ້ອມ​ກັນ​ເພື່ອ​ຖອດ​ໝຸດ."</string>
-    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ມັນ​ຈະ​ຮັກ​ສາ​ໜ້າ​ຈໍ​ໄວ້​ໃນ​ມຸມມອງ​ຂອງ​ທ່ານ​ຈົນ​ກວ່າ​ທ່ານ​ຈະ​ຖອດ​ໝຸດ. ​ສຳ​ຜັດ​ປຸ່ມ ພາບ​ຮວມ​ ຄ້າງ​ໄວ້​ເພື່ອ​ຖອດ​ໝຸດ."</string>
+    <string name="screen_pinning_description" msgid="1346522416878235405">"ມັນ​ຈະ​ຮັກ​ສາ​ໜ້າ​ຈໍ​ໄວ້​ໃນ​ມຸມມອງ​ຂອງ​ທ່ານ​ຈົນ​ກວ່າ​ທ່ານ​ຈະ​ຖອດ​ໝຸດ. ​ແຕະ​ປຸ່ມ ກັບ​ຄືນ ແລະ ພາບ​ຮວມ​ ຄ້າງ​ໄວ້​ພ້ອມ​ກັນ​ເພື່ອ​ຖອດ​ໝຸດ."</string>
+    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ມັນ​ຈະ​ຮັກ​ສາ​ໜ້າ​ຈໍ​ໄວ້​ໃນ​ມຸມມອງ​ຂອງ​ທ່ານ​ຈົນ​ກວ່າ​ທ່ານ​ຈະ​ຖອດ​ໝຸດ. ​ແຕະ​ປຸ່ມ ພາບ​ຮວມ​ ຄ້າງ​ໄວ້​ເພື່ອ​ຖອດ​ໝຸດ."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ເຂົ້າໃຈແລ້ວ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ບໍ່, ຂອບໃຈ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ເຊື່ອງ <xliff:g id="TILE_LABEL">%1$s</xliff:g> ຫຼື​ບໍ່?"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4e19700..060b1c5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -319,7 +319,7 @@
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Opnieuw starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, doorgaan"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"Nieuwe gebruiker toevoegen?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Wanneer u een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\n1Elke gebruiker kan apps bijwerken voor alle andere gebruikers."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Wanneer u een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\n1Elke gebruiker kan apps updaten voor alle andere gebruikers."</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Accubesparing is ingeschakeld"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Vermindert de prestaties en achtergrondgegevens"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Accubesparing uitschakelen"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 4d76f38..5b18b24 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -131,6 +131,9 @@
     <integer name="quick_settings_brightness_dialog_short_timeout">2000</integer>
     <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
 
+    <!-- The maximum number of items to be displayed in quick settings -->
+    <integer name="quick_settings_detail_max_item_count">7</integer>
+
     <integer name="blinds_pop_duration_ms">10</integer>
 
     <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7ac0daf..e66934e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -964,11 +964,10 @@
 
         // if the setup wizard hasn't run yet, don't show
         final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
-        final boolean absent = mUpdateMonitor.getNextSubIdForState(
-                IccCardConstants.State.ABSENT) != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        final boolean disabled = mUpdateMonitor.getNextSubIdForState(
-                IccCardConstants.State.PERM_DISABLED)
-                != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        final boolean absent = SubscriptionManager.isValidSubscriptionId(
+                mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
+        final boolean disabled = SubscriptionManager.isValidSubscriptionId(
+                mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
         final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                 || ((absent || disabled) && requireSim);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
new file mode 100644
index 0000000..cfe8d07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -0,0 +1,76 @@
+/*
+ * 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.systemui.qs;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+/**
+ * Wrapper view with background which contains {@link QSPanel}
+ */
+public class QSContainer extends FrameLayout {
+
+    private int mHeightOverride = -1;
+    private QSPanel mQSPanel;
+
+    public QSContainer(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mQSPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        updateBottom();
+    }
+
+    /**
+     * Overrides the height of this view (post-layout), so that the content is clipped to that
+     * height and the background is set to that height.
+     *
+     * @param heightOverride the overridden height
+     */
+    public void setHeightOverride(int heightOverride) {
+        mHeightOverride = heightOverride;
+        updateBottom();
+    }
+
+    /**
+     * The height this view wants to be. This is different from {@link #getMeasuredHeight} such that
+     * during closing the detail panel, this already returns the smaller height.
+     */
+    public int getDesiredHeight() {
+        if (mQSPanel.isClosingDetail()) {
+            return mQSPanel.getGridHeight() + getPaddingTop() + getPaddingBottom();
+        } else {
+            return getMeasuredHeight();
+        }
+    }
+
+    private void updateBottom() {
+        int height = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
+        setBottom(getTop() + height);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
index a311d6e..9155102 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
@@ -51,8 +51,10 @@
     private boolean mItemsVisible = true;
     private LinearLayout mItems;
     private View mEmpty;
+    private View mMinHeightSpacer;
     private TextView mEmptyText;
     private ImageView mEmptyIcon;
+    private int mMaxItems;
 
     public QSDetailItems(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -77,6 +79,12 @@
         mEmpty.setVisibility(GONE);
         mEmptyText = (TextView) mEmpty.findViewById(android.R.id.title);
         mEmptyIcon = (ImageView) mEmpty.findViewById(android.R.id.icon);
+        mMinHeightSpacer = findViewById(R.id.min_height_spacer);
+
+        // By default, a detail item view has fixed size.
+        mMaxItems = getResources().getInteger(
+                R.integer.quick_settings_detail_max_item_count);
+        setMinHeightInItems(mMaxItems);
     }
 
     @Override
@@ -102,6 +110,16 @@
         mEmptyText.setText(text);
     }
 
+    /**
+     * Set the minimum height of this detail view, in item count.
+     */
+    public void setMinHeightInItems(int minHeightInItems) {
+        ViewGroup.LayoutParams lp = mMinHeightSpacer.getLayoutParams();
+        lp.height = minHeightInItems * getResources().getDimensionPixelSize(
+                R.dimen.qs_detail_item_height);
+        mMinHeightSpacer.setLayoutParams(lp);
+    }
+
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
@@ -135,7 +153,7 @@
     }
 
     private void handleSetItems(Item[] items) {
-        final int itemCount = items != null ? items.length : 0;
+        final int itemCount = items != null ? Math.min(items.length, mMaxItems) : 0;
         mEmpty.setVisibility(itemCount == 0 ? VISIBLE : GONE);
         mItems.setVisibility(itemCount == 0 ? GONE : VISIBLE);
         for (int i = mItems.getChildCount() - 1; i >= itemCount; i--) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 91b1569..974235e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -67,8 +67,10 @@
     private int mPanelPaddingBottom;
     private int mDualTileUnderlap;
     private int mBrightnessPaddingTop;
+    private int mGridHeight;
     private boolean mExpanded;
     private boolean mListening;
+    private boolean mClosingDetail;
 
     private Record mDetailRecord;
     private Callback mCallback;
@@ -320,6 +322,14 @@
         showDetail(false, mDetailRecord);
     }
 
+    public boolean isClosingDetail() {
+        return mClosingDetail;
+    }
+
+    public int getGridHeight() {
+        return mGridHeight;
+    }
+
     private void handleShowDetail(Record r, boolean show) {
         if (r instanceof TileRecord) {
             handleShowDetailTile((TileRecord) r, show);
@@ -364,6 +374,7 @@
             setDetailRecord(r);
             listener = mHideGridContentWhenDone;
         } else {
+            mClosingDetail = true;
             setGridContentVisibility(true);
             listener = mTeardownDetailWhenDone;
             fireScanStateChanged(false);
@@ -426,6 +437,7 @@
         if (mDetail.getMeasuredHeight() < h) {
             mDetail.measure(exactly(width), exactly(h));
         }
+        mGridHeight = h;
         setMeasuredDimension(width, Math.max(h, mDetail.getMeasuredHeight()));
     }
 
@@ -537,6 +549,7 @@
         public void onAnimationEnd(Animator animation) {
             mDetailContent.removeAllViews();
             setDetailRecord(null);
+            mClosingDetail = false;
         };
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 1bc1d77..c15566f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -185,6 +185,7 @@
             mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
                     R.string.quick_settings_bluetooth_detail_empty_text);
             mItems.setCallback(this);
+            mItems.setMinHeightInItems(0);
             updateItems();
             setItemsVisible(mState.value);
             return mItems;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 6e710ef..fcc517f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -88,9 +88,7 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed()
-                && !(mController.isProvisioningNeeded() && mKeyguard.isSecure()
-                && mKeyguard.isShowing());
+        state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed();
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         state.value = mController.isHotspotEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index 9a55590..e9f3cf9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityOptions;
 import android.content.ActivityNotFoundException;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -44,16 +45,29 @@
 
     // Which recents to use
     boolean mUseAlternateRecents = true;
-    AlternateRecentsComponent mAlternateRecents;
     boolean mBootCompleted = false;
+    static AlternateRecentsComponent sAlternateRecents;
+
+    /** Returns the Recents component, creating a new one in-process if necessary. */
+    public static AlternateRecentsComponent getRecentsComponent(Context context,
+            boolean forceInitialize) {
+        if (sAlternateRecents == null) {
+            sAlternateRecents = new AlternateRecentsComponent(context);
+            if (forceInitialize) {
+                sAlternateRecents.onStart();
+                sAlternateRecents.onBootCompleted();
+            }
+        }
+        return sAlternateRecents;
+    }
 
     @Override
     public void start() {
         if (mUseAlternateRecents) {
-            if (mAlternateRecents == null) {
-                mAlternateRecents = new AlternateRecentsComponent(mContext);
+            if (sAlternateRecents == null) {
+                sAlternateRecents = getRecentsComponent(mContext, false);
             }
-            mAlternateRecents.onStart();
+            sAlternateRecents.onStart();
         }
 
         putComponent(RecentsComponent.class, this);
@@ -62,8 +76,8 @@
     @Override
     protected void onBootCompleted() {
         if (mUseAlternateRecents) {
-            if (mAlternateRecents != null) {
-                mAlternateRecents.onBootCompleted();
+            if (sAlternateRecents != null) {
+                sAlternateRecents.onBootCompleted();
             }
         }
         mBootCompleted = true;
@@ -72,14 +86,14 @@
     @Override
     public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onShowRecents(triggeredFromAltTab, statusBarView);
+            sAlternateRecents.onShowRecents(triggeredFromAltTab);
         }
     }
 
     @Override
     public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
+            sAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
         } else {
             Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
             intent.setPackage("com.android.systemui");
@@ -93,7 +107,7 @@
     public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
         if (mUseAlternateRecents) {
             // Launch the alternate recents if required
-            mAlternateRecents.onToggleRecents(statusBarView);
+            sAlternateRecents.onToggleRecents();
             return;
         }
 
@@ -241,14 +255,14 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onConfigurationChanged(newConfig);
+            sAlternateRecents.onConfigurationChanged(newConfig);
         }
     }
 
     @Override
     public void preloadRecents() {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onPreloadRecents();
+            sAlternateRecents.onPreloadRecents();
         } else {
             Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
             intent.setClassName("com.android.systemui",
@@ -262,7 +276,7 @@
     @Override
     public void cancelPreloadingRecents() {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onCancelPreloadingRecents();
+            sAlternateRecents.onCancelPreloadingRecents();
         } else {
             Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
             intent.setClassName("com.android.systemui",
@@ -276,21 +290,21 @@
     @Override
     public void showNextAffiliatedTask() {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onShowNextAffiliatedTask();
+            sAlternateRecents.onShowNextAffiliatedTask();
         }
     }
 
     @Override
     public void showPrevAffiliatedTask() {
         if (mUseAlternateRecents) {
-            mAlternateRecents.onShowPrevAffiliatedTask();
+            sAlternateRecents.onShowPrevAffiliatedTask();
         }
     }
 
     @Override
     public void setCallback(Callbacks cb) {
         if (mUseAlternateRecents) {
-            mAlternateRecents.setRecentsComponentCallback(cb);
+            sAlternateRecents.setRecentsComponentCallback(cb);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index f1bf66d..3e6611a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -27,6 +27,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -38,7 +39,6 @@
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
-
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.recents.misc.Console;
@@ -57,12 +57,27 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+/**
+ * Annotation for a method that is only called from the primary user's SystemUI process and will be
+ * proxied to the current user.
+ */
+@interface ProxyFromPrimaryToCurrentUser {}
+/**
+ * Annotation for a method that may be called from any user's SystemUI process and will be proxied
+ * to the primary user.
+ */
+@interface ProxyFromAnyToPrimaryUser {}
 
 /** A proxy implementation for the recents component */
 public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
 
-    final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
-    final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
+    final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "triggeredFromAltTab";
+    final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "triggeredFromHomeKey";
+    final public static String EXTRA_RECENTS_VISIBILITY = "recentsVisibility";
+
+    // Owner proxy events
+    final public static String ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER =
+            "action_notify_recents_visibility_change";
 
     final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
     final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
@@ -78,24 +93,60 @@
      * An implementation of ITaskStackListener, that allows us to listen for changes to the system
      * task stacks and update recents accordingly.
      */
-    class TaskStackListenerImpl extends ITaskStackListener.Stub {
+    class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
+        Handler mHandler;
+
+        public TaskStackListenerImpl(Handler handler) {
+            mHandler = handler;
+        }
+
         @Override
         public void onTaskStackChanged() {
+            // Debounce any task stack changes
+            mHandler.removeCallbacks(this);
+            mHandler.post(this);
+        }
+
+        /** Preloads the next task */
+        public void run() {
             RecentsConfiguration config = RecentsConfiguration.getInstance();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+                ActivityManager.RunningTaskInfo runningTaskInfo = getTopMostTask();
+
                 // Load the next task only if we aren't svelte
                 RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
                 loader.preloadTasks(plan, true /* isTopTaskHome */);
                 RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
-                launchOpts.numVisibleTasks = 1;
-                launchOpts.numVisibleTaskThumbnails = 1;
+                // This callback is made when a new activity is launched and the old one is paused
+                // so ignore the current activity and try and preload the thumbnail for the
+                // previous one.
+                if (runningTaskInfo != null) {
+                    launchOpts.runningTaskId = runningTaskInfo.id;
+                }
+                launchOpts.numVisibleTasks = 2;
+                launchOpts.numVisibleTaskThumbnails = 2;
                 launchOpts.onlyLoadForCache = true;
+                launchOpts.onlyLoadPausedActivities = true;
                 loader.loadTasks(mContext, plan, launchOpts);
             }
         }
     }
 
+    /**
+     * A proxy for Recents events which happens strictly for the owner.
+     */
+    class RecentsOwnerEventProxyReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            switch (intent.getAction()) {
+                case ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER:
+                    visibilityChanged(intent.getBooleanExtra(EXTRA_RECENTS_VISIBILITY, false));
+                    break;
+            }
+        }
+    }
+
     static RecentsComponent.Callbacks sRecentsComponentCallbacks;
     static RecentsTaskLoadPlan sInstanceLoadPlan;
 
@@ -104,6 +155,7 @@
     SystemServicesProxy mSystemServicesProxy;
     Handler mHandler;
     TaskStackListenerImpl mTaskStackListener;
+    RecentsOwnerEventProxyReceiver mProxyBroadcastReceiver;
     boolean mBootCompleted;
     boolean mStartAnimationTriggered;
     boolean mCanReuseTaskStackViews = true;
@@ -123,7 +175,6 @@
     TaskStackView mDummyStackView;
 
     // Variables to keep track of if we need to start recents after binding
-    View mStatusBarView;
     boolean mTriggeredFromAltTab;
     long mLastToggleTime;
 
@@ -136,30 +187,37 @@
         mTaskStackBounds = new Rect();
 
         // Register the task stack listener
-        mTaskStackListener = new TaskStackListenerImpl();
+        mTaskStackListener = new TaskStackListenerImpl(mHandler);
         mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
+
+        // Only the owner has the callback to update the SysUI visibility flags, so all non-owner
+        // instances of AlternateRecentsComponent needs to notify the owner when the visibility
+        // changes.
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver();
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(AlternateRecentsComponent.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
+            mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter,
+                    null, mHandler);
+        }
     }
 
+    /** Creates a new broadcast intent */
+    static Intent createLocalBroadcastIntent(Context context, String action) {
+        Intent intent = new Intent(action);
+        intent.setPackage(context.getPackageName());
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+                Intent.FLAG_RECEIVER_FOREGROUND);
+        return intent;
+    }
+
+    /** Initializes the Recents. */
+    @ProxyFromPrimaryToCurrentUser
     public void onStart() {
         // Initialize some static datastructures
         TaskStackViewLayoutAlgorithm.initializeCurve();
         // Load the header bar layout
-        reloadHeaderBarLayout();
-        // Try and pre-emptively bind the search widget on startup to ensure that we
-        // have the right thumbnail bounds to animate to.
-        if (Constants.DebugFlags.App.EnableSearchLayout) {
-            // If there is no id, then bind a new search app widget
-            if (mConfig.searchBarAppWidgetId < 0) {
-                AppWidgetHost host = new RecentsAppWidgetHost(mContext,
-                        Constants.Values.App.AppWidgetHostId);
-                Pair<Integer, AppWidgetProviderInfo> widgetInfo =
-                        mSystemServicesProxy.bindSearchAppWidget(host);
-                if (widgetInfo != null) {
-                    // Save the app widget id into the settings
-                    mConfig.updateSearchBarAppWidgetId(mContext, widgetInfo.first);
-                }
-            }
-        }
+        reloadHeaderBarLayout(true);
 
         // When we start, preload the data associated with the previous recent tasks.
         // We can use a new plan since the caches will be the same.
@@ -177,9 +235,19 @@
         mBootCompleted = true;
     }
 
-    /** Shows the recents */
-    public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) {
-        mStatusBarView = statusBarView;
+    /** Shows the Recents. */
+    @ProxyFromPrimaryToCurrentUser
+    public void onShowRecents(boolean triggeredFromAltTab) {
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            showRecents(triggeredFromAltTab);
+        } else {
+            Intent intent = createLocalBroadcastIntent(mContext,
+                    RecentsUserEventProxyReceiver.ACTION_PROXY_SHOW_RECENTS_TO_USER);
+            intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+        }
+    }
+    void showRecents(boolean triggeredFromAltTab) {
         mTriggeredFromAltTab = triggeredFromAltTab;
 
         try {
@@ -189,16 +257,25 @@
         }
     }
 
-    /** Hides the recents */
+    /** Hides the Recents. */
+    @ProxyFromPrimaryToCurrentUser
     public void onHideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
+        } else {
+            Intent intent = createLocalBroadcastIntent(mContext,
+                    RecentsUserEventProxyReceiver.ACTION_PROXY_HIDE_RECENTS_TO_USER);
+            intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
+            intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
+            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+        }
+    }
+    void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mBootCompleted) {
             ActivityManager.RunningTaskInfo topTask = getTopMostTask();
             if (topTask != null && isRecentsTopMost(topTask, null)) {
                 // Notify recents to hide itself
-                Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY);
-                intent.setPackage(mContext.getPackageName());
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
-                        Intent.FLAG_RECEIVER_FOREGROUND);
+                Intent intent = createLocalBroadcastIntent(mContext, ACTION_HIDE_RECENTS_ACTIVITY);
                 intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
                 intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
@@ -206,9 +283,18 @@
         }
     }
 
-    /** Toggles the alternate recents activity */
-    public void onToggleRecents(View statusBarView) {
-        mStatusBarView = statusBarView;
+    /** Toggles the Recents activity. */
+    @ProxyFromPrimaryToCurrentUser
+    public void onToggleRecents() {
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            toggleRecents();
+        } else {
+            Intent intent = createLocalBroadcastIntent(mContext,
+                    RecentsUserEventProxyReceiver.ACTION_PROXY_TOGGLE_RECENTS_TO_USER);
+            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+        }
+    }
+    void toggleRecents() {
         mTriggeredFromAltTab = false;
 
         try {
@@ -218,7 +304,18 @@
         }
     }
 
+    /** Preloads info for the Recents activity. */
+    @ProxyFromPrimaryToCurrentUser
     public void onPreloadRecents() {
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            preloadRecents();
+        } else {
+            Intent intent = createLocalBroadcastIntent(mContext,
+                    RecentsUserEventProxyReceiver.ACTION_PROXY_PRELOAD_RECENTS_TO_USER);
+            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+        }
+    }
+    void preloadRecents() {
         // Preload only the raw task list into a new load plan (which will be consumed by the
         // RecentsActivity)
         RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
@@ -309,15 +406,26 @@
         showRelativeAffiliatedTask(false);
     }
 
+    /** Updates on configuration change. */
+    @ProxyFromPrimaryToCurrentUser
     public void onConfigurationChanged(Configuration newConfig) {
+        if (mSystemServicesProxy.isForegroundUserOwner()) {
+            configurationChanged();
+        } else {
+            Intent intent = createLocalBroadcastIntent(mContext,
+                    RecentsUserEventProxyReceiver.ACTION_PROXY_CONFIG_CHANGE_TO_USER);
+            mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+        }
+    }
+    void configurationChanged() {
         // Don't reuse task stack views if the configuration changes
         mCanReuseTaskStackViews = false;
         // Reload the header bar layout
-        reloadHeaderBarLayout();
+        reloadHeaderBarLayout(false);
     }
 
     /** Prepares the header bar layout. */
-    void reloadHeaderBarLayout() {
+    void reloadHeaderBarLayout(boolean reloadWidget) {
         Resources res = mContext.getResources();
         mWindowRect = mSystemServicesProxy.getWindowRect();
         mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
@@ -325,6 +433,10 @@
         mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
         mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
         mConfig.updateOnConfigurationChange();
+        if (reloadWidget) {
+            // Reload the widget id before we get the task stack bounds
+            reloadSearchBarAppWidget(mContext, mSystemServicesProxy);
+        }
         mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
                 (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds);
         if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
@@ -350,6 +462,24 @@
         mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight);
     }
 
+    /** Prepares the search bar app widget */
+    void reloadSearchBarAppWidget(Context context, SystemServicesProxy ssp) {
+        // Try and pre-emptively bind the search widget on startup to ensure that we
+        // have the right thumbnail bounds to animate to.
+        if (Constants.DebugFlags.App.EnableSearchLayout) {
+            // If there is no id, then bind a new search app widget
+            if (mConfig.searchBarAppWidgetId < 0) {
+                AppWidgetHost host = new RecentsAppWidgetHost(context,
+                        Constants.Values.App.AppWidgetHostId);
+                Pair<Integer, AppWidgetProviderInfo> widgetInfo = ssp.bindSearchAppWidget(host);
+                if (widgetInfo != null) {
+                    // Save the app widget id into the settings
+                    mConfig.updateSearchBarAppWidgetId(context, widgetInfo.first);
+                }
+            }
+        }
+    }
+
     /** Gets the top task. */
     ActivityManager.RunningTaskInfo getTopMostTask() {
         SystemServicesProxy ssp = mSystemServicesProxy;
@@ -397,10 +527,7 @@
         AtomicBoolean isTopTaskHome = new AtomicBoolean(true);
         if (topTask != null && isRecentsTopMost(topTask, isTopTaskHome)) {
             // Notify recents to toggle itself
-            Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY);
-            intent.setPackage(mContext.getPackageName());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
-                    Intent.FLAG_RECEIVER_FOREGROUND);
+            Intent intent = createLocalBroadcastIntent(mContext, ACTION_TOGGLE_RECENTS_ACTIVITY);
             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             mLastToggleTime = SystemClock.elapsedRealtime();
             return;
@@ -474,7 +601,7 @@
             }
 
             mStartAnimationTriggered = false;
-            return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mStatusBarView,
+            return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
                     thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(),
                     toTaskRect.height(), this);
         }
@@ -623,7 +750,19 @@
     }
 
     /** Notifies the callbacks that the visibility of Recents has changed. */
-    public static void notifyVisibilityChanged(boolean visible) {
+    @ProxyFromAnyToPrimaryUser
+    public static void notifyVisibilityChanged(Context context, SystemServicesProxy ssp,
+            boolean visible) {
+        if (ssp.isForegroundUserOwner()) {
+            visibilityChanged(visible);
+        } else {
+            Intent intent = createLocalBroadcastIntent(context,
+                    ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
+            intent.putExtra(EXTRA_RECENTS_VISIBILITY, visible);
+            context.sendBroadcastAsUser(intent, UserHandle.OWNER);
+        }
+    }
+    static void visibilityChanged(boolean visible) {
         if (sRecentsComponentCallbacks != null) {
             sRecentsComponentCallbacks.onVisibilityChanged(visible);
         }
@@ -667,10 +806,7 @@
             };
 
             // Send the broadcast to notify Recents that the animation has started
-            Intent intent = new Intent(ACTION_START_ENTER_ANIMATION);
-            intent.setPackage(mContext.getPackageName());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
-                    Intent.FLAG_RECEIVER_FOREGROUND);
+            Intent intent = createLocalBroadcastIntent(mContext, ACTION_START_ENTER_ANIMATION);
             mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
                     fallbackReceiver, null, Activity.RESULT_CANCELED, null, null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 6baff96..ee631f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -434,7 +434,9 @@
     protected void onStart() {
         super.onStart();
         mVisible = true;
-        AlternateRecentsComponent.notifyVisibilityChanged(true);
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        SystemServicesProxy ssp = loader.getSystemServicesProxy();
+        AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, true);
 
         // Register the broadcast receiver to handle messages from our service
         IntentFilter filter = new IntentFilter();
@@ -444,7 +446,7 @@
         registerReceiver(mServiceBroadcastReceiver, filter);
 
         // Register any broadcast receivers for the task loader
-        RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
+        loader.registerReceivers(this, mRecentsView);
 
         // Update the recent tasks
         updateRecentsTasks(getIntent());
@@ -454,7 +456,9 @@
     protected void onStop() {
         super.onStop();
         mVisible = false;
-        AlternateRecentsComponent.notifyVisibilityChanged(false);
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        SystemServicesProxy ssp = loader.getSystemServicesProxy();
+        AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, false);
 
         // Notify the views that we are no longer visible
         mRecentsView.onRecentsHidden();
@@ -463,7 +467,7 @@
         unregisterReceiver(mServiceBroadcastReceiver);
 
         // Unregister any broadcast receivers for the task loader
-        RecentsTaskLoader.getInstance().unregisterReceivers();
+        loader.unregisterReceivers();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java
new file mode 100644
index 0000000..236da5db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java
@@ -0,0 +1,70 @@
+/*
+ * 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.systemui.recents;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import com.android.systemui.recent.Recents;
+
+
+/**
+ * A proxy for Recents events which happens strictly for non-owner users.
+ */
+public class RecentsUserEventProxyReceiver extends BroadcastReceiver {
+    final public static String ACTION_PROXY_SHOW_RECENTS_TO_USER =
+            "com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER";
+    final public static String ACTION_PROXY_HIDE_RECENTS_TO_USER =
+            "com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER";
+    final public static String ACTION_PROXY_TOGGLE_RECENTS_TO_USER =
+            "com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER";
+    final public static String ACTION_PROXY_PRELOAD_RECENTS_TO_USER =
+            "com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER";
+    final public static String ACTION_PROXY_CONFIG_CHANGE_TO_USER =
+            "com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        AlternateRecentsComponent recents = Recents.getRecentsComponent(
+                context.getApplicationContext(), true);
+        switch (intent.getAction()) {
+            case ACTION_PROXY_SHOW_RECENTS_TO_USER: {
+                boolean triggeredFromAltTab = intent.getBooleanExtra(
+                        AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
+                recents.showRecents(triggeredFromAltTab);
+                break;
+            }
+            case ACTION_PROXY_HIDE_RECENTS_TO_USER: {
+                boolean triggeredFromAltTab = intent.getBooleanExtra(
+                        AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
+                boolean triggeredFromHome = intent.getBooleanExtra(
+                        AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false);
+                recents.hideRecents(triggeredFromAltTab, triggeredFromHome);
+                break;
+            }
+            case ACTION_PROXY_TOGGLE_RECENTS_TO_USER:
+                recents.toggleRecents();
+                break;
+            case ACTION_PROXY_PRELOAD_RECENTS_TO_USER:
+                recents.preloadRecents();
+                break;
+            case ACTION_PROXY_CONFIG_CHANGE_TO_USER:
+                recents.configurationChanged();
+                break;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 3fbd5a6..542f21c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -49,14 +49,12 @@
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.IWindowManager;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -396,6 +394,15 @@
     }
 
     /**
+     * Returns whether the foreground user is the owner.
+     */
+    public boolean isForegroundUserOwner() {
+        if (mAm == null) return false;
+
+        return mAm.getCurrentUser() == UserHandle.USER_OWNER;
+    }
+
+    /**
      * Resolves and returns the first Recents widget from the same package as the global
      * assist activity.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 0011811..0e1c01a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -50,6 +50,7 @@
         public boolean loadIcons = true;
         public boolean loadThumbnails = true;
         public boolean onlyLoadForCache = false;
+        public boolean onlyLoadPausedActivities = false;
         public int numVisibleTasks = 0;
         public int numVisibleTaskThumbnails = 0;
     }
@@ -141,6 +142,7 @@
                     activityColor, (i == (taskCount - 1)), mConfig.lockToAppEnabled, icon,
                     iconFilename);
             task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy, false);
+            if (DEBUG) Log.d(TAG, "\tthumbnail: " + taskKey + ", " + task.thumbnail);
             loadedTasks.add(task);
         }
         mStack.setTasks(loadedTasks);
@@ -186,6 +188,11 @@
             boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
             boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
 
+            // If requested, skip the running task
+            if (opts.onlyLoadPausedActivities && isRunningTask) {
+                continue;
+            }
+
             if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
                 if (task.activityIcon == null) {
                     if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
@@ -194,7 +201,7 @@
                 }
             }
             if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
-                if (task.thumbnail == null) {
+                if (task.thumbnail == null || isRunningTask) {
                     if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
                     if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
                         task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 7b60307..465a141 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -25,8 +25,6 @@
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
@@ -43,7 +41,6 @@
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
@@ -355,11 +352,14 @@
             if (mActivated) {
                 mBackgroundDimmed.setVisibility(View.VISIBLE);
                 mBackgroundNormal.setVisibility(View.VISIBLE);
-            } else {
+            } else if (mDimmed) {
                 mBackgroundDimmed.setVisibility(View.VISIBLE);
                 mBackgroundNormal.setVisibility(View.INVISIBLE);
+            } else {
+                mBackgroundDimmed.setVisibility(View.INVISIBLE);
+                mBackgroundNormal.setVisibility(View.VISIBLE);
             }
-            fadeDarkToDimmed(delay);
+            fadeInFromDark(delay);
         } else {
             updateBackground();
         }
@@ -401,15 +401,16 @@
     }
 
     /**
-     * Fades the dimmed background when exiting dark mode.
+     * Fades in the background when exiting dark mode.
      */
-    private void fadeDarkToDimmed(long delay) {
-        mBackgroundDimmed.setAlpha(0f);
-        mBackgroundDimmed.setPivotX(mBackgroundDimmed.getWidth() / 2f);
-        mBackgroundDimmed.setPivotY(getActualHeight() / 2f);
-        mBackgroundDimmed.setScaleX(DARK_EXIT_SCALE_START);
-        mBackgroundDimmed.setScaleY(DARK_EXIT_SCALE_START);
-        mBackgroundDimmed.animate()
+    private void fadeInFromDark(long delay) {
+        final View background = mDimmed ? mBackgroundDimmed : mBackgroundNormal;
+        background.setAlpha(0f);
+        background.setPivotX(mBackgroundDimmed.getWidth() / 2f);
+        background.setPivotY(getActualHeight() / 2f);
+        background.setScaleX(DARK_EXIT_SCALE_START);
+        background.setScaleY(DARK_EXIT_SCALE_START);
+        background.animate()
                 .alpha(1f)
                 .scaleX(1f)
                 .scaleY(1f)
@@ -420,9 +421,9 @@
                     @Override
                     public void onAnimationCancel(Animator animation) {
                         // Jump state if we are cancelled
-                        mBackgroundDimmed.setScaleX(1f);
-                        mBackgroundDimmed.setScaleY(1f);
-                        mBackgroundDimmed.setAlpha(1f);
+                        background.setScaleX(1f);
+                        background.setScaleY(1f);
+                        background.setAlpha(1f);
                     }
                 })
                 .start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedImageView.java
new file mode 100644
index 0000000..094161d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedImageView.java
@@ -0,0 +1,51 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * An ImageView which does not have overlapping rendering commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class AlphaOptimizedImageView extends ImageView
+{
+    public AlphaOptimizedImageView(Context context) {
+        super(context);
+    }
+
+    public AlphaOptimizedImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AlphaOptimizedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public AlphaOptimizedImageView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 0faad21..914b3d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -124,6 +124,7 @@
         mContractedChild = child;
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
         selectLayout(false /* animate */, true /* force */);
+        mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
     }
 
     public void setExpandedChild(View child) {
@@ -245,6 +246,7 @@
     public void notifyContentUpdated() {
         selectLayout(false /* animate */, true /* force */);
         if (mContractedChild != null) {
+            mContractedWrapper.notifyContentUpdated();
             mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
index 5b6e1cd..fbcba0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
@@ -26,6 +26,7 @@
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
@@ -40,17 +41,18 @@
  */
 public class NotificationTemplateViewWrapper extends NotificationViewWrapper {
 
-    private final ViewInvertHelper mInvertHelper;
-    private final ImageView mIcon;
-    protected final ImageView mPicture;
     private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
     private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
             0, PorterDuff.Mode.SRC_ATOP);
     private final int mIconDarkAlpha;
-    private final int mIconBackgroundColor;
     private final int mIconBackgroundDarkColor;
     private final Interpolator mLinearOutSlowInInterpolator;
 
+    private int mIconBackgroundColor;
+    private ViewInvertHelper mInvertHelper;
+    private ImageView mIcon;
+    protected ImageView mPicture;
+
     protected NotificationTemplateViewWrapper(Context ctx, View view) {
         super(view);
         mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
@@ -58,12 +60,16 @@
                 ctx.getResources().getColor(R.color.doze_small_icon_background_color);
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
                 android.R.interpolator.linear_out_slow_in);
-        View mainColumn = view.findViewById(com.android.internal.R.id.notification_main_column);
+        resolveViews();
+    }
+
+    private void resolveViews() {
+        View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column);
         mInvertHelper = mainColumn != null
                 ? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION)
                 : null;
-        ImageView largeIcon = (ImageView) view.findViewById(com.android.internal.R.id.icon);
-        ImageView rightIcon = (ImageView) view.findViewById(com.android.internal.R.id.right_icon);
+        ImageView largeIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
+        ImageView rightIcon = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon);
         mIcon = resolveIcon(largeIcon, rightIcon);
         mPicture = resolvePicture(largeIcon);
         mIconBackgroundColor = resolveBackgroundColor(mIcon);
@@ -92,6 +98,14 @@
     }
 
     @Override
+    public void notifyContentUpdated() {
+        super.notifyContentUpdated();
+
+        // Reinspect the notification.
+        resolveViews();
+    }
+
+    @Override
     public void setDark(boolean dark, boolean fade, long delay) {
         if (mInvertHelper != null) {
             if (fade) {
@@ -180,7 +194,13 @@
     private void updateIconColorFilter(ImageView target, float intensity) {
         int color = interpolateColor(mIconBackgroundColor, mIconBackgroundDarkColor, intensity);
         mIconColorFilter.setColor(color);
-        target.getBackground().mutate().setColorFilter(mIconColorFilter);
+        Drawable background = target.getBackground();
+
+        // The notification might have been modified during the animation, so background might be
+        // null here.
+        if (background != null) {
+            background.mutate().setColorFilter(mIconColorFilter);
+        }
     }
 
     private void updateIconAlpha(ImageView target, boolean dark) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
index 0a02573..78b9739 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
@@ -53,4 +53,9 @@
      * @param delay if fading, the delay of the animation
      */
     public abstract void setDark(boolean dark, boolean fade, long delay);
+
+    /**
+     * Notifies this wrapper that the content of the view might have changed.
+     */
+    public void notifyContentUpdated() {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 8e50abe..8e35ee99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -277,9 +277,13 @@
                     mWifiStrengthId));
 
         boolean anyMobileVisible = false;
+        int firstMobileTypeId = 0;
         for (PhoneState state : mPhoneStates) {
             if (state.apply(anyMobileVisible)) {
-                anyMobileVisible = true;
+                if (!anyMobileVisible) {
+                    firstMobileTypeId = state.mMobileTypeId;
+                    anyMobileVisible = true;
+                }
             }
         }
 
@@ -298,7 +302,7 @@
             mWifiAirplaneSpacer.setVisibility(View.GONE);
         }
 
-        if ((anyMobileVisible || mNoSimsVisible) && mWifiVisible) {
+        if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
             mWifiSignalSpacer.setVisibility(View.VISIBLE);
         } else {
             mWifiSignalSpacer.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 08844f31..1b00e59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -40,6 +40,7 @@
 
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.R;
+import com.android.systemui.qs.QSContainer;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -71,7 +72,7 @@
     private StatusBarHeaderView mHeader;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
     private KeyguardStatusBarView mKeyguardStatusBar;
-    private View mQsContainer;
+    private QSContainer mQsContainer;
     private QSPanel mQsPanel;
     private KeyguardStatusView mKeyguardStatusView;
     private ObservableScrollView mScrollView;
@@ -161,6 +162,7 @@
     private boolean mKeyguardStatusViewAnimating;
     private boolean mHeaderAnimatingIn;
     private ObjectAnimator mQsContainerAnimator;
+    private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShadeEmpty;
 
@@ -188,7 +190,7 @@
         mHeader.setOnClickListener(this);
         mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
         mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
-        mQsContainer = findViewById(R.id.quick_settings_container);
+        mQsContainer = (QSContainer) findViewById(R.id.quick_settings_container);
         mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
         mClockView = (TextView) findViewById(R.id.clock_view);
         mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
@@ -283,21 +285,35 @@
         mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize());
 
         // Calculate quick setting heights.
+        int oldMaxHeight = mQsMaxExpansionHeight;
         mQsMinExpansionHeight = mKeyguardShowing ? 0 : mHeader.getCollapsedHeight() + mQsPeekHeight;
-        mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
+        mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getDesiredHeight();
         positionClockAndNotifications();
-        if (mQsExpanded) {
-            if (mQsFullyExpanded) {
-                mQsExpansionHeight = mQsMaxExpansionHeight;
-                requestScrollerTopPaddingUpdate(false /* animate */);
+        if (mQsExpanded && mQsFullyExpanded) {
+            mQsExpansionHeight = mQsMaxExpansionHeight;
+            requestScrollerTopPaddingUpdate(false /* animate */);
+            requestPanelHeightUpdate();
+
+            // Size has changed, start an animation.
+            if (mQsMaxExpansionHeight != oldMaxHeight) {
+                startQsSizeChangeAnimation(oldMaxHeight, mQsMaxExpansionHeight);
             }
-        } else {
+        } else if (!mQsExpanded) {
             setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
-            mNotificationStackScroller.setStackHeight(getExpandedHeight());
         }
+        mNotificationStackScroller.setStackHeight(getExpandedHeight());
         updateHeader();
         mNotificationStackScroller.updateIsSmallScreen(
                 mHeader.getCollapsedHeight() + mQsPeekHeight);
+
+        // If we are running a size change animation, the animation takes care of the height of
+        // the container. However, if we are not animating, we always need to make the QS container
+        // the desired height so when closing the QS detail, it stays smaller after the size change
+        // animation is finished but the detail view is still being animated away (this animation
+        // takes longer than the size change animation).
+        if (mQsSizeChangeAnimator == null) {
+            mQsContainer.setHeightOverride(mQsContainer.getDesiredHeight());
+        }
     }
 
     @Override
@@ -310,6 +326,32 @@
         mSecureCameraLaunchManager.destroy();
     }
 
+    private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
+        if (mQsSizeChangeAnimator != null) {
+            oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
+            mQsSizeChangeAnimator.cancel();
+        }
+        mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight);
+        mQsSizeChangeAnimator.setDuration(300);
+        mQsSizeChangeAnimator.setInterpolator(mFastOutSlowInInterpolator);
+        mQsSizeChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                requestScrollerTopPaddingUpdate(false /* animate */);
+                requestPanelHeightUpdate();
+                int height = (int) mQsSizeChangeAnimator.getAnimatedValue();
+                mQsContainer.setHeightOverride(height - mHeader.getExpandedHeight());
+            }
+        });
+        mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mQsSizeChangeAnimator = null;
+            }
+        });
+        mQsSizeChangeAnimator.start();
+    }
+
     /**
      * Positions the clock and notifications dynamically depending on how many notifications are
      * showing.
@@ -1113,7 +1155,7 @@
 
     private void setQsTranslation(float height) {
         if (!mHeaderAnimatingIn) {
-            mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation());
+            mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation());
         }
         if (mKeyguardShowing) {
             mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0));
@@ -1137,6 +1179,8 @@
                     : maxQs;
             return (int) interpolate(getExpandedFraction(),
                     mQsMinExpansionHeight, max);
+        } else if (mQsSizeChangeAnimator != null) {
+            return (int) mQsSizeChangeAnimator.getAnimatedValue();
         } else if (mKeyguardShowing && mScrollYOverride == -1) {
 
             // We can only do the smoother transition on Keyguard when we also are not collapsing
@@ -1348,14 +1392,20 @@
                     + mNotificationStackScroller.getBottomStackPeekSize()
                     + mNotificationStackScroller.getCollapseSecondCardPadding();
         }
+        int maxQsHeight = mQsMaxExpansionHeight;
+
+        // If an animation is changing the size of the QS panel, take the animated value.
+        if (mQsSizeChangeAnimator != null) {
+            maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
+        }
         float totalHeight = Math.max(
-                mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(),
+                maxQsHeight + mNotificationStackScroller.getNotificationTopPadding(),
                 mStatusBarState == StatusBarState.KEYGUARD
                         ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment
                         : 0)
                 + notificationHeight;
         if (totalHeight > mNotificationStackScroller.getHeight()) {
-            float fullyCollapsedHeight = mQsMaxExpansionHeight
+            float fullyCollapsedHeight = maxQsHeight
                     + mNotificationStackScroller.getMinStackHeight()
                     + mNotificationStackScroller.getNotificationTopPadding()
                     - getScrollViewScrollY();
@@ -1629,6 +1679,7 @@
         } else {
             mSecureCameraLaunchManager.startSecureCameraLaunch();
         }
+        mStatusBar.startLaunchTransitionTimeout();
         mBlockTouches = true;
     }
 
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 ec2d30c..8b328aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -203,8 +203,12 @@
     private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
     private static final int MSG_CLOSE_PANELS = 1001;
     private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
+    private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
     // 1020-1040 reserved for BaseStatusBar
 
+    // Time after we abort the launch transition.
+    private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
+
     private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
 
     private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
@@ -2196,6 +2200,9 @@
                     escalateHeadsUp();
                     setHeadsUpVisibility(false);
                     break;
+                case MSG_LAUNCH_TRANSITION_TIMEOUT:
+                    onLaunchTransitionTimeout();
+                    break;
             }
         }
     }
@@ -3528,12 +3535,10 @@
         if (mLaunchTransitionFadingAway) {
             mNotificationPanel.animate().cancel();
             mNotificationPanel.setAlpha(1f);
-            if (mLaunchTransitionEndRunnable != null) {
-                mLaunchTransitionEndRunnable.run();
-            }
-            mLaunchTransitionEndRunnable = null;
+            runLaunchTransitionEndRunnable();
             mLaunchTransitionFadingAway = false;
         }
+        mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
         setBarState(StatusBarState.KEYGUARD);
         updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
         if (!mScreenOnFromKeyguard) {
@@ -3574,6 +3579,7 @@
      */
     public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
             Runnable endRunnable) {
+        mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
         mLaunchTransitionEndRunnable = endRunnable;
         Runnable hideRunnable = new Runnable() {
             @Override
@@ -3592,10 +3598,7 @@
                             @Override
                             public void run() {
                                 mNotificationPanel.setAlpha(1);
-                                if (mLaunchTransitionEndRunnable != null) {
-                                    mLaunchTransitionEndRunnable.run();
-                                }
-                                mLaunchTransitionEndRunnable = null;
+                                runLaunchTransitionEndRunnable();
                                 mLaunchTransitionFadingAway = false;
                             }
                         });
@@ -3609,6 +3612,32 @@
     }
 
     /**
+     * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
+     * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
+     * because the launched app crashed or something else went wrong.
+     */
+    public void startLaunchTransitionTimeout() {
+        mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
+                LAUNCH_TRANSITION_TIMEOUT_MS);
+    }
+
+    private void onLaunchTransitionTimeout() {
+        Log.w(TAG, "Launch transition: Timeout!");
+        mNotificationPanel.resetViews();
+    }
+
+    private void runLaunchTransitionEndRunnable() {
+        if (mLaunchTransitionEndRunnable != null) {
+            Runnable r = mLaunchTransitionEndRunnable;
+
+            // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
+            // which would lead to infinite recursion. Protect against it.
+            mLaunchTransitionEndRunnable = null;
+            r.run();
+        }
+    }
+
+    /**
      * @return true if we would like to stay in the shade, false if it should go away entirely
      */
     public boolean hideKeyguard() {
@@ -3631,6 +3660,7 @@
         if (mQSPanel != null) {
             mQSPanel.refreshAllTiles();
         }
+        mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
         return staying;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 247252c..181926c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -777,9 +777,11 @@
                 v.bringToFront();
                 v.setVisibility(VISIBLE);
             }
+            if (v.hasOverlappingRendering()) {
+                v.animate().withLayer();
+            }
             v.animate()
                     .alpha(in ? 1 : 0)
-                    .withLayer()
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 77da70a..f4edab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -199,7 +199,7 @@
                         new Runnable() {
                             @Override
                             public void run() {
-                                mStatusBarWindowManager.setKeyguardOccluded(true);
+                                mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
                                 reset();
                             }
                         });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 80fec5b..229c558 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -19,15 +19,21 @@
 import static android.bluetooth.BluetoothAdapter.ERROR;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.connectionStateToString;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.deviceToString;
-import static com.android.systemui.statusbar.policy.BluetoothUtil.profileStateToString;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.profileToString;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToProfile;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidToString;
 import static com.android.systemui.statusbar.policy.BluetoothUtil.uuidsToString;
 
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothA2dpSink;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothInputDevice;
 import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothMap;
+import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothProfile.ServiceListener;
 import android.content.BroadcastReceiver;
@@ -38,24 +44,37 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.SparseBooleanArray;
+import android.util.SparseArray;
 
 import com.android.systemui.statusbar.policy.BluetoothUtil.Profile;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 public class BluetoothControllerImpl implements BluetoothController {
     private static final String TAG = "BluetoothController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    // This controls the order in which we check the states.  Since a device can only have
+    // one state on screen, but can have multiple profiles, the later states override the
+    // value of earlier states.  So if a device has a profile in CONNECTING and one in
+    // CONNECTED, it will show as CONNECTED, theoretically this shouldn't really happen often,
+    // but seemed worth noting.
+    private static final int[] CONNECTION_STATES = {
+        BluetoothProfile.STATE_DISCONNECTED,
+        BluetoothProfile.STATE_DISCONNECTING,
+        BluetoothProfile.STATE_CONNECTING,
+        BluetoothProfile.STATE_CONNECTED,
+    };
 
     private final Context mContext;
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final BluetoothAdapter mAdapter;
     private final Receiver mReceiver = new Receiver();
     private final ArrayMap<BluetoothDevice, DeviceInfo> mDeviceInfo = new ArrayMap<>();
+    private final SparseArray<BluetoothProfile> mProfiles = new SparseArray<>();
 
     private boolean mEnabled;
     private boolean mConnecting;
@@ -73,7 +92,8 @@
 
         mReceiver.register();
         setAdapterState(mAdapter.getState());
-        updateBondedBluetoothDevices();
+        updateBluetoothDevices();
+        bindAllProfiles();
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -83,6 +103,7 @@
         pw.print("  mConnecting="); pw.println(mConnecting);
         pw.print("  mLastDevice="); pw.println(mLastDevice);
         pw.print("  mCallbacks.size="); pw.println(mCallbacks.size());
+        pw.print("  mProfiles="); pw.println(profilesToString(mProfiles));
         pw.print("  mDeviceInfo.size="); pw.println(mDeviceInfo.size());
         for (int i = 0; i < mDeviceInfo.size(); i++) {
             final BluetoothDevice device = mDeviceInfo.keyAt(i);
@@ -95,7 +116,22 @@
 
     private static String infoToString(DeviceInfo info) {
         return info == null ? null : ("connectionState=" +
-                connectionStateToString(info.connectionState) + ",bonded=" + info.bonded);
+                connectionStateToString(info.connectionState) + ",bonded=" + info.bonded
+                + ",profiles=" + profilesToString(info.connectedProfiles));
+    }
+
+    private static String profilesToString(SparseArray<?> profiles) {
+        final int N = profiles.size();
+        final StringBuffer buffer = new StringBuffer();
+        buffer.append('[');
+        for (int i = 0; i < N; i++) {
+            if (i != 0) {
+                buffer.append(',');
+            }
+            buffer.append(BluetoothUtil.profileToString(profiles.keyAt(i)));
+        }
+        buffer.append(']');
+        return buffer.toString();
     }
 
     public void addStateChangedCallback(Callback cb) {
@@ -178,6 +214,7 @@
     private void connect(PairedDevice pd, final boolean connect) {
         if (mAdapter == null || pd == null || pd.tag == null) return;
         final BluetoothDevice device = (BluetoothDevice) pd.tag;
+        final DeviceInfo info = mDeviceInfo.get(device);
         final String action = connect ? "connect" : "disconnect";
         if (DEBUG) Log.d(TAG, action + " " + deviceToString(device));
         final ParcelUuid[] uuids = device.getUuids();
@@ -185,43 +222,35 @@
             Log.w(TAG, "No uuids returned, aborting " + action + " for " + deviceToString(device));
             return;
         }
-        final SparseBooleanArray profiles = new SparseBooleanArray();
-        for (ParcelUuid uuid : uuids) {
-            final int profile = uuidToProfile(uuid);
-            if (profile == 0) {
-                Log.w(TAG, "Device " + deviceToString(device) + " has an unsupported uuid: "
-                        + uuidToString(uuid));
-                continue;
+        SparseArray<Boolean> profiles = new SparseArray<>();
+        if (connect) {
+            // When connecting add every profile we can recognize by uuid.
+            for (ParcelUuid uuid : uuids) {
+                final int profile = uuidToProfile(uuid);
+                if (profile == 0) {
+                    Log.w(TAG, "Device " + deviceToString(device) + " has an unsupported uuid: "
+                            + uuidToString(uuid));
+                    continue;
+                }
+                final boolean connected = info.connectedProfiles.get(profile, false);
+                if (!connected) {
+                    profiles.put(profile, true);
+                }
             }
-            final int profileState = mAdapter.getProfileConnectionState(profile);
-            if (DEBUG && !profiles.get(profile)) Log.d(TAG, "Profile " + profileToString(profile)
-                    + " state = " + profileStateToString(profileState));
-            final boolean connected = profileState == BluetoothProfile.STATE_CONNECTED;
-            if (connect != connected) {
-                profiles.put(profile, true);
-            }
+        } else {
+            // When disconnecting, just add every profile we know they are connected to.
+            profiles = info.connectedProfiles;
         }
         for (int i = 0; i < profiles.size(); i++) {
             final int profile = profiles.keyAt(i);
-            mAdapter.getProfileProxy(mContext, new ServiceListener() {
-                @Override
-                public void onServiceConnected(int profile, BluetoothProfile proxy) {
-                    if (DEBUG) Log.d(TAG, "onServiceConnected " + profileToString(profile));
-                    final Profile p = BluetoothUtil.getProfile(proxy);
-                    if (p == null) {
-                        Log.w(TAG, "Unable get get Profile for " + profileToString(profile));
-                    } else {
-                        final boolean ok = connect ? p.connect(device) : p.disconnect(device);
-                        if (DEBUG) Log.d(TAG, action + " " + profileToString(profile) + " "
-                                + (ok ? "succeeded" : "failed"));
-                    }
-                }
-
-                @Override
-                public void onServiceDisconnected(int profile) {
-                    if (DEBUG) Log.d(TAG, "onServiceDisconnected " + profileToString(profile));
-                }
-            }, profile);
+            if (mProfiles.indexOfKey(profile) >= 0) {
+                final Profile p = BluetoothUtil.getProfile(mProfiles.get(profile));
+                final boolean ok = connect ? p.connect(device) : p.disconnect(device);
+                if (DEBUG) Log.d(TAG, action + " " + profileToString(profile) + " "
+                        + (ok ? "succeeded" : "failed"));
+            } else {
+                Log.w(TAG, "Unable get get Profile for " + profileToString(profile));
+            }
         }
     }
 
@@ -230,11 +259,13 @@
         return mLastDevice != null ? mLastDevice.getAliasName() : null;
     }
 
-    private void updateBondedBluetoothDevices() {
+    private void updateBluetoothDevices() {
         if (mAdapter == null) return;
         final Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
         for (DeviceInfo info : mDeviceInfo.values()) {
             info.bonded = false;
+            info.connectionState = ERROR;
+            info.connectedProfiles.clear();
         }
         int bondedCount = 0;
         BluetoothDevice lastBonded = null;
@@ -248,12 +279,64 @@
                 }
             }
         }
+        final int N = mProfiles.size();
+        final int[] connectionType = new int[1];
+        for (int i = 0; i < CONNECTION_STATES.length; i++) {
+            connectionType[0] = CONNECTION_STATES[i];
+            for (int j = 0; j < N; j++) {
+                int profile = mProfiles.keyAt(j);
+                List<BluetoothDevice> devices = mProfiles.get(profile)
+                        .getDevicesMatchingConnectionStates(connectionType);
+                for (int k = 0; k < devices.size(); k++) {
+                    DeviceInfo info = mDeviceInfo.get(devices.get(k));
+                    if (info != null) {
+                        info.connectionState = CONNECTION_STATES[i];
+                        if (CONNECTION_STATES[i] == BluetoothProfile.STATE_CONNECTED) {
+                            info.connectedProfiles.put(profile, true);
+                        }
+                    }
+                }
+            }
+        }
         if (mLastDevice == null && bondedCount == 1) {
             mLastDevice = lastBonded;
         }
+        // If we are no longer connected to the current device, see if we are connected to
+        // something else, so we don't display a name we aren't connected to.
+        if (mLastDevice != null &&
+                mDeviceInfo.get(mLastDevice).connectionState != BluetoothProfile.STATE_CONNECTED) {
+            // Make sure we don't keep this device while it isn't connected.
+            mLastDevice = null;
+            // Look for anything else connected.
+            final int size = mDeviceInfo.size();
+            for (int i = 0; i < size; i++) {
+                BluetoothDevice device = mDeviceInfo.keyAt(i);
+                DeviceInfo info = mDeviceInfo.valueAt(i);
+                if (info.connectionState == BluetoothProfile.STATE_CONNECTED) {
+                    mLastDevice = device;
+                    break;
+                }
+            }
+        }
         firePairedDevicesChanged();
     }
 
+    private void bindAllProfiles() {
+        // Note: This needs to contain all of the types that can be returned by BluetoothUtil
+        // otherwise we can't find the profiles we need when we connect/disconnect.
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP_SINK);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.AVRCP_CONTROLLER);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET_CLIENT);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.INPUT_DEVICE);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.MAP);
+        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.PAN);
+        // Note Health is not in this list because health devices aren't 'connected'.
+        // If profiles are expanded to use more than just connection state and connect/disconnect
+        // then it should be added.
+    }
+
     private void firePairedDevicesChanged() {
         for (Callback cb : mCallbacks) {
             cb.onBluetoothPairedDevicesChanged();
@@ -283,6 +366,20 @@
         cb.onBluetoothStateChange(mEnabled, mConnecting);
     }
 
+    private final ServiceListener mProfileListener = new ServiceListener() {
+        @Override
+        public void onServiceDisconnected(int profile) {
+            mProfiles.remove(profile);
+            updateBluetoothDevices();
+        }
+
+        @Override
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mProfiles.put(profile, proxy);
+            updateBluetoothDevices();
+        }
+    };
+
     private final class Receiver extends BroadcastReceiver {
         public void register() {
             final IntentFilter filter = new IntentFilter();
@@ -290,6 +387,15 @@
             filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
             filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
             filter.addAction(BluetoothDevice.ACTION_ALIAS_CHANGED);
+            filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED);
+            filter.addAction(BluetoothDevice.ACTION_UUID);
+            filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
+            filter.addAction(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
             mContext.registerReceiver(this, filter);
         }
 
@@ -301,16 +407,13 @@
                 setAdapterState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, ERROR));
                 if (DEBUG) Log.d(TAG, "ACTION_STATE_CHANGED " + mEnabled);
             } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
-                final DeviceInfo info = updateInfo(device);
+                updateInfo(device);
                 final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
                         ERROR);
-                if (state != ERROR) {
-                    info.connectionState = state;
-                }
                 mLastDevice = device;
                 if (DEBUG) Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED "
                         + connectionStateToString(state) + " " + deviceToString(device));
-                setConnecting(info.connectionState == BluetoothAdapter.STATE_CONNECTING);
+                setConnecting(state == BluetoothAdapter.STATE_CONNECTING);
             } else if (action.equals(BluetoothDevice.ACTION_ALIAS_CHANGED)) {
                 updateInfo(device);
                 mLastDevice = device;
@@ -318,7 +421,8 @@
                 if (DEBUG) Log.d(TAG, "ACTION_BOND_STATE_CHANGED " + device);
                 // we'll update all bonded devices below
             }
-            updateBondedBluetoothDevices();
+            // Always update bluetooth devices state.
+            updateBluetoothDevices();
         }
     }
 
@@ -332,5 +436,6 @@
     private static class DeviceInfo {
         int connectionState = BluetoothAdapter.STATE_DISCONNECTED;
         boolean bonded;  // per getBondedDevices
+        SparseArray<Boolean> connectedProfiles = new SparseArray<>();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java
index 1b4be85..ed8ac2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothUtil.java
@@ -36,7 +36,10 @@
         if (profile == BluetoothProfile.HEADSET) return "HEADSET";
         if (profile == BluetoothProfile.A2DP) return "A2DP";
         if (profile == BluetoothProfile.AVRCP_CONTROLLER) return "AVRCP_CONTROLLER";
-        return "UNKNOWN";
+        if (profile == BluetoothProfile.PAN) return "PAN";
+        if (profile == BluetoothProfile.INPUT_DEVICE) return "INPUT_DEVICE";
+        if (profile == BluetoothProfile.MAP) return "MAP";
+        return "UNKNOWN(" + profile + ")";
     }
 
     public static String profileStateToString(int state) {
@@ -106,6 +109,11 @@
 
         if (BluetoothUuid.AvrcpController.equals(uuid)) return BluetoothProfile.AVRCP_CONTROLLER;
 
+        if (BluetoothUuid.Hid.equals(uuid)) return BluetoothProfile.INPUT_DEVICE;
+        if (BluetoothUuid.Hogp.equals(uuid)) return BluetoothProfile.INPUT_DEVICE;
+
+        if (BluetoothUuid.NAP.equals(uuid)) return BluetoothProfile.PAN;
+
         return 0;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index b05cb31..5f7d452 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -36,6 +36,14 @@
 
     private static final String TAG = "HotspotController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    // Keep these in sync with Settings TetherService.java
+    public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
+    public static final String EXTRA_SET_ALARM = "extraSetAlarm";
+    public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
+    public static final String EXTRA_ENABLE_WIFI_TETHER = "extraEnableWifiTether";
+    // Keep this in sync with Settings TetherSettings.java
+    public static final int WIFI_TETHERING = 0;
+
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final Receiver mReceiver = new Receiver();
     private final Context mContext;
@@ -97,9 +105,13 @@
                 String tetherEnable = mContext.getResources().getString(
                         com.android.internal.R.string.config_wifi_tether_enable);
                 Intent intent = new Intent();
+                intent.putExtra(EXTRA_ADD_TETHER_TYPE, WIFI_TETHERING);
+                intent.putExtra(EXTRA_SET_ALARM, true);
+                intent.putExtra(EXTRA_RUN_PROVISION, true);
+                intent.putExtra(EXTRA_ENABLE_WIFI_TETHER, true);
                 intent.setComponent(ComponentName.unflattenFromString(tetherEnable));
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                mContext.startServiceAsUser(intent, UserHandle.CURRENT);
             } else {
                 int wifiState = mWifiManager.getWifiState();
                 if ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
index 30da9cb..af51266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
@@ -196,6 +196,7 @@
     }
 
     public void setMobileDataEnabled(boolean enabled) {
+        Log.d(TAG, "setMobileDataEnabled: enabled=" + enabled);
         mTelephonyManager.setDataEnabled(enabled);
         if (mCallback != null) {
             mCallback.onMobileDataEnabled(enabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 6431ab5..81c6da5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -21,7 +21,6 @@
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -49,6 +48,7 @@
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants;
@@ -92,7 +92,7 @@
     private final ConnectivityManager mConnectivityManager;
     private final SubscriptionManager mSubscriptionManager;
     private final boolean mHasMobileDataFeature;
-    private final Config mConfig;
+    private Config mConfig;
 
     // Subcontrollers.
     @VisibleForTesting
@@ -265,14 +265,14 @@
 
     private MobileSignalController getDataController() {
         int dataSubId = SubscriptionManager.getDefaultDataSubId();
-        if (dataSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+        if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
             if (DEBUG) Log.e(TAG, "No data sim selected");
             return mDefaultSignalController;
         }
         if (mMobileSignalControllers.containsKey(dataSubId)) {
             return mMobileSignalControllers.get(dataSubId);
         }
-        Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
+        if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
         return mDefaultSignalController;
     }
 
@@ -283,8 +283,9 @@
 
     public boolean isEmergencyOnly() {
         int voiceSubId = SubscriptionManager.getDefaultVoiceSubId();
-        if (voiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
+            for (MobileSignalController mobileSignalController :
+                                            mMobileSignalControllers.values()) {
                 if (!mobileSignalController.isEmergencyOnly()) {
                     return false;
                 }
@@ -293,7 +294,7 @@
         if (mMobileSignalControllers.containsKey(voiceSubId)) {
             return mMobileSignalControllers.get(voiceSubId).isEmergencyOnly();
         }
-        Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
+        if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
         // Something is wrong, better assume we can't make calls...
         return true;
     }
@@ -376,8 +377,8 @@
             updateConnectivity();
             refreshCarrierLabel();
         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
-            refreshLocale();
-            refreshCarrierLabel();
+            mConfig = Config.readConfig(mContext);
+            handleConfigurationChanged();
         } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
             refreshLocale();
             updateAirplaneMode(false);
@@ -397,7 +398,7 @@
         } else {
             int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            if (SubscriptionManager.isValidSubscriptionId(subId)) {
                 if (mMobileSignalControllers.containsKey(subId)) {
                     mMobileSignalControllers.get(subId).handleBroadcast(intent);
                 } else {
@@ -411,6 +412,15 @@
         }
     }
 
+    @VisibleForTesting
+    void handleConfigurationChanged() {
+        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+            mobileSignalController.setConfiguration(mConfig);
+        }
+        refreshLocale();
+        refreshCarrierLabel();
+    }
+
     private void updateMobileControllers() {
         if (!mListening) {
             return;
@@ -483,6 +493,10 @@
                 cachedControllers.get(key).unregisterListener();
             }
         }
+        // There may be new MobileSignalControllers around, make sure they get the current
+        // inet condition and airplane mode.
+        pushConnectivityToSignals();
+        updateAirplaneMode(true /* force */);
     }
 
     private boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) {
@@ -577,6 +591,13 @@
         mBluetoothTethered = mConnectedTransports.get(TRANSPORT_BLUETOOTH);
         mEthernetConnected = mConnectedTransports.get(TRANSPORT_ETHERNET);
 
+        pushConnectivityToSignals();
+    }
+
+    /**
+     * Pushes the current connectivity state to all SignalControllers.
+     */
+    private void pushConnectivityToSignals() {
         // We want to update all the icons, all at once, for any condition change
         for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
             mobileSignalController.setInetCondition(
@@ -971,7 +992,6 @@
     // TODO: Move to its own file.
     static class MobileSignalController extends SignalController<MobileSignalController.MobileState,
             MobileSignalController.MobileIconGroup> {
-        private final Config mConfig;
         private final TelephonyManager mPhone;
         private final String mNetworkNameDefault;
         private final String mNetworkNameSeparator;
@@ -981,7 +1001,7 @@
         private final SubscriptionInfo mSubscriptionInfo;
 
         // @VisibleForDemoMode
-        Map<Integer, MobileIconGroup> mNetworkToIconLookup;
+        final SparseArray<MobileIconGroup> mNetworkToIconLookup;
 
         // Since some pieces of the phone state are interdependent we store it locally,
         // this could potentially become part of MobileState for simplification/complication
@@ -992,6 +1012,7 @@
         private ServiceState mServiceState;
         private SignalStrength mSignalStrength;
         private MobileIconGroup mDefaultIcons;
+        private Config mConfig;
 
         // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
         // need listener lists anymore.
@@ -1002,6 +1023,7 @@
             super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
                     NetworkCapabilities.TRANSPORT_CELLULAR, signalCallbacks, signalClusters,
                     networkController);
+            mNetworkToIconLookup = new SparseArray<>();
             mConfig = config;
             mPhone = phone;
             mSubscriptionInfo = info;
@@ -1019,6 +1041,12 @@
             updateDataSim();
         }
 
+        public void setConfiguration(Config config) {
+            mConfig = config;
+            mapIconSets();
+            updateTelephony();
+        }
+
         /**
          * Get (the mobile parts of) the carrier string.
          *
@@ -1103,12 +1131,9 @@
         /**
          * Produce a mapping of data network types to icon groups for simple and quick use in
          * updateTelephony.
-         *
-         * TODO: See if config can change with locale, this may need to be regenerated on Locale
-         * change.
          */
         private void mapIconSets() {
-            mNetworkToIconLookup = new HashMap<Integer, MobileIconGroup>();
+            mNetworkToIconLookup.clear();
 
             mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
             mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
@@ -1254,7 +1279,7 @@
 
         private void updateDataSim() {
             int defaultDataSub = SubscriptionManager.getDefaultDataSubId();
-            if (SubscriptionManager.isValidSubId(defaultDataSub)) {
+            if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
                 mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
             } else {
                 // There doesn't seem to be a data sim selected, however if
@@ -1312,7 +1337,7 @@
                     mCurrentState.level = mSignalStrength.getLevel();
                 }
             }
-            if (mNetworkToIconLookup.containsKey(mDataNetType)) {
+            if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
                 mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
             } else {
                 mCurrentState.iconGroup = mDefaultIcons;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 2a393bf..6dcbed6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2280,8 +2280,7 @@
                 updateContentHeight();
                 notifyHeightChangeListener(mDismissView);
             } else {
-                mEmptyShadeView.setWillBeGone(true);
-                mEmptyShadeView.performVisibilityAnimation(false, new Runnable() {
+                Runnable onFinishedRunnable = new Runnable() {
                     @Override
                     public void run() {
                         mEmptyShadeView.setVisibility(GONE);
@@ -2289,7 +2288,14 @@
                         updateContentHeight();
                         notifyHeightChangeListener(mDismissView);
                     }
-                });
+                };
+                if (mAnimationsEnabled) {
+                    mEmptyShadeView.setWillBeGone(true);
+                    mEmptyShadeView.performVisibilityAnimation(false, onFinishedRunnable);
+                } else {
+                    mEmptyShadeView.setInvisible();
+                    onFinishedRunnable.run();
+                }
             }
         }
     }
@@ -2318,7 +2324,7 @@
                         notifyHeightChangeListener(mDismissView);
                     }
                 };
-                if (mDismissView.isButtonVisible() && mIsExpanded) {
+                if (mDismissView.isButtonVisible() && mIsExpanded && mAnimationsEnabled) {
                     mDismissView.setWillBeGone(true);
                     mDismissView.performVisibilityAnimation(false, dimissHideFinishRunnable);
                 } else {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 020bc00..d85b059 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -4,9 +4,17 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
 import android.content.Intent;
 import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
+import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
@@ -22,14 +30,6 @@
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
 
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-
 public class NetworkControllerBaseTest extends AndroidTestCase {
     private static final String TAG = "NetworkControllerBaseTest";
     protected static final int DEFAULT_LEVEL = 2;
@@ -52,6 +52,8 @@
     protected TelephonyManager mMockTm;
     protected Config mConfig;
 
+    private NetworkCapabilities mNetCapabilities;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -63,7 +65,10 @@
         mMockTm = mock(TelephonyManager.class);
         mMockSm = mock(SubscriptionManager.class);
         mMockCm = mock(ConnectivityManager.class);
+        mNetCapabilities = new NetworkCapabilities();
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
+        when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
+                new NetworkCapabilities[] { mNetCapabilities });
 
         mSignalStrength = mock(SignalStrength.class);
         mServiceState = mock(ServiceState.class);
@@ -115,13 +120,18 @@
 
     public void setConnectivity(int inetCondition, int networkType, boolean isConnected) {
         Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
-        NetworkInfo networkInfo = mock(NetworkInfo.class);
-        when(networkInfo.isConnected()).thenReturn(isConnected);
-        when(networkInfo.getType()).thenReturn(networkType);
-        when(networkInfo.getTypeName()).thenReturn("");
-        when(mMockCm.getActiveNetworkInfo()).thenReturn(networkInfo);
+        // TODO: Separate out into several NetworkCapabilities.
+        if (isConnected) {
+            mNetCapabilities.addTransportType(networkType);
+        } else {
+            mNetCapabilities.removeTransportType(networkType);
+        }
+        if (inetCondition != 0) {
+            mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+        } else {
+            mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+        }
 
-        i.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, inetCondition);
         mNetworkController.onReceive(mContext, i);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index e327233..3f9312d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -1,9 +1,9 @@
 package com.android.systemui.statusbar.policy;
 
+import org.mockito.Mockito;
+
 import android.telephony.TelephonyManager;
 
-// WARNING: Many of these tests may fail with config showMin3G.
-// TODO: Maybe fix the above.
 public class NetworkControllerDataTest extends NetworkControllerBaseTest {
 
     public void test3gDataIcon() {
@@ -57,7 +57,6 @@
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_LTE);
 
-        // WARNING: May fail depending on config.
         verifyDataIndicators(TelephonyIcons.DATA_LTE[1][0 /* No direction */],
                 TelephonyIcons.QS_DATA_LTE[1]);
     }
@@ -67,11 +66,42 @@
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_HSPA);
 
-        // WARNING: May fail depending on config.
         verifyDataIndicators(TelephonyIcons.DATA_H[1][0 /* No direction */],
                 TelephonyIcons.QS_DATA_H[1]);
     }
 
+    public void test4gDataIcon() {
+        // Switch to showing 4g icon and re-initialize the NetworkController.
+        mConfig.show4gForLte = true;
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
+                mConfig, Mockito.mock(AccessPointControllerImpl.class),
+                Mockito.mock(MobileDataControllerImpl.class));
+        setupNetworkController();
+
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        verifyDataIndicators(TelephonyIcons.DATA_4G[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_4G[1]);
+    }
+
+    public void test4gDataIconConfigChange() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        // Switch to showing 4g icon and re-initialize the NetworkController.
+        mConfig.show4gForLte = true;
+        // Can't send the broadcast as that would actually read the config from
+        // the context.  Instead we'll just poke at a function that does all of
+        // the after work.
+        mNetworkController.handleConfigurationChanged();
+
+        verifyDataIndicators(TelephonyIcons.DATA_4G[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_4G[1]);
+    }
+
     public void testDataActivity() {
         setupDefaultSignal();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 33eb4d6..27a4052 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -60,7 +60,7 @@
                     DEFAULT_ICON);
 
             // Verify low inet number indexing.
-            setConnectivity(10, ConnectivityManager.TYPE_MOBILE, true);
+            setConnectivity(0, ConnectivityManager.TYPE_MOBILE, true);
             verifyLastMobileDataIndicators(true,
                     TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], 0);
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 7f0a8f4..2e0e9a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -27,7 +27,7 @@
 
             setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
             verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
-            setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+            setConnectivity(0, ConnectivityManager.TYPE_WIFI, true);
             verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
         }
     }
@@ -48,7 +48,7 @@
             setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
                     testSsid);
-            setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+            setConnectivity(0, ConnectivityManager.TYPE_WIFI, true);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
                     testSsid);
         }
@@ -75,22 +75,6 @@
         verifyLastQsDataDirection(true, true);
     }
 
-    public void testNoDataIconDuringWifi() {
-        // Setup normal connection
-        String testSsid = "Test SSID";
-        int testLevel = 2;
-        setWifiEnabled(true);
-        setWifiState(true, testSsid);
-        setWifiLevel(testLevel);
-        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
-        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
-
-        setupDefaultSignal();
-        // Still be on wifi though.
-        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
-        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0 /* No icon */);
-    }
-
     public void testRoamingIconDuringWifi() {
         // Setup normal connection
         String testSsid = "Test SSID";
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 8b53a62..f0c6bb7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2165,7 +2165,6 @@
                 }
                 mStatusBar = win;
                 mStatusBarController.setWindow(win);
-                mKeyguardDelegate.hideScrim();
                 break;
             case TYPE_NAVIGATION_BAR:
                 mContext.enforceCallingOrSelfPermission(
@@ -2453,6 +2452,15 @@
                     return -1;
                 }
 
+                // If an incoming call is ringing, HOME is totally disabled.
+                // (The user is already on the InCallUI at this point,
+                // and his ONLY options are to answer or reject the call.)
+                TelecomManager telecomManager = getTelecommService();
+                if (telecomManager != null && telecomManager.isRinging()) {
+                    Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+                    return -1;
+                }
+
                 // Delay handling home if a double-tap is possible.
                 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
                     mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 618ba1e..6e8f550 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -37,6 +37,7 @@
     private final Context mContext;
     private final View mScrim; // shown if keyguard crashes
     private final KeyguardState mKeyguardState = new KeyguardState();
+    private ShowListener mShowListenerWhenConnect;
 
     /* package */ static final class KeyguardState {
         KeyguardState() {
@@ -46,6 +47,7 @@
             showing = true;
             showingAndNotOccluded = true;
             secure = true;
+            deviceHasKeyguard = true;
         }
         boolean showing;
         boolean showingAndNotOccluded;
@@ -54,6 +56,7 @@
         boolean secure;
         boolean dreaming;
         boolean systemIsReady;
+        boolean deviceHasKeyguard;
         public boolean enabled;
         public boolean dismissable;
         public int offReason;
@@ -111,10 +114,12 @@
         intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
         if (!context.bindServiceAsUser(intent, mKeyguardConnection,
                 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
-            if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
+            Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
             mKeyguardState.showing = false;
             mKeyguardState.showingAndNotOccluded = false;
             mKeyguardState.secure = false;
+            mKeyguardState.deviceHasKeyguard = false;
+            hideScrim();
         } else {
             if (DEBUG) Log.v(TAG, "*** Keyguard started");
         }
@@ -130,7 +135,9 @@
                 // If the system is ready, it means keyguard crashed and restarted.
                 mKeyguardService.onSystemReady();
                 // This is used to hide the scrim once keyguard displays.
-                mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null));
+                mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(
+                        mShowListenerWhenConnect));
+                mShowListenerWhenConnect = null;
             }
             if (mKeyguardState.bootCompleted) {
                 mKeyguardService.onBootCompleted();
@@ -212,9 +219,10 @@
         } else {
             // try again when we establish a connection
             Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!");
-            // This shouldn't happen, but if it does, invoke the listener immediately
-            // to avoid a dark screen...
-            showListener.onShown(null);
+            // This shouldn't happen, but if it does, show the scrim immediately and
+            // invoke the listener's callback after the service actually connects.
+            mShowListenerWhenConnect = showListener;
+            showScrim();
         }
         mKeyguardState.screenIsOn = true;
     }
@@ -280,7 +288,6 @@
         lp.setTitle("KeyguardScrim");
         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         wm.addView(view, lp);
-        view.setVisibility(View.GONE);
         // Disable pretty much everything in statusbar until keyguard comes back and we know
         // the state of the world.
         view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
@@ -292,6 +299,7 @@
     }
 
     public void showScrim() {
+        if (!mKeyguardState.deviceHasKeyguard) return;
         mScrim.post(new Runnable() {
             @Override
             public void run() {
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 6c5c508..e86c461 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1184,6 +1184,13 @@
             mApplicationContext = ctx.getApplicationContext();
         }
         mRWLock = new ReentrantReadWriteLock();
+        try {
+            registerNativeAllocation.invoke(sRuntime, 4 * 1024 * 1024); // 4MB for GC sake
+        } catch (Exception e) {
+            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
+            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
+        }
+
     }
 
     /**
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 89aebe8..5ae26ef 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2145,6 +2145,9 @@
                 if (!permissionGranted) {
                     return null;
                 }
+                if (mSecurityPolicy.mWindows == null) {
+                    return null;
+                }
                 List<AccessibilityWindowInfo> windows = new ArrayList<>();
                 final int windowCount = mSecurityPolicy.mWindows.size();
                 for (int i = 0; i < windowCount; i++) {
@@ -3421,7 +3424,7 @@
                 return false;
             }
 
-            // Windows are ordered in z order so start from the botton and find
+            // Windows are ordered in z order so start from the bottom and find
             // the window of interest. After that all windows that cover it should
             // be subtracted from the resulting region. Note that for accessibility
             // we are returning only interactive windows.
@@ -3439,7 +3442,8 @@
                         windowInteractiveRegion = outRegion;
                         continue;
                     }
-                } else {
+                } else if (currentWindow.getType()
+                        != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
                     Rect currentWindowBounds = mTempRect;
                     currentWindow.getBoundsInScreen(currentWindowBounds);
                     if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 47bf188..a9a756e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -61,7 +61,6 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Locale;
-import java.util.Random;
 import java.util.TimeZone;
 
 import static android.app.AlarmManager.RTC_WAKEUP;
@@ -115,12 +114,8 @@
     final Object mLock = new Object();
 
     long mNativeData;
-
-    private final Random mFuzzer = new Random();
-    private long mNextWakeupBatchStart;     // nominal start of next wakeup's delivery window
-    private long mNextWakeup;               // actual scheduled next wakeup within that window
+    private long mNextWakeup;
     private long mNextNonWakeup;
-
     int mBroadcastRefCount = 0;
     PowerManager.WakeLock mWakeLock;
     boolean mLastWakeLockUnimportantForLogging;
@@ -372,27 +367,14 @@
 
     static class BatchTimeOrder implements Comparator<Batch> {
         public int compare(Batch b1, Batch b2) {
-            final long start1 = b1.start;
-            final long start2 = b2.start;
-            if (start1 > start2) {
+            long when1 = b1.start;
+            long when2 = b2.start;
+            if (when1 - when2 > 0) {
                 return 1;
             }
-            if (start1 < start2) {
+            if (when1 - when2 < 0) {
                 return -1;
             }
-
-            // Identical trigger times.  As a secondary ordering, require that
-            // the batch with the shorter allowable delivery window sorts first.
-            final long interval1 = b1.end - b1.start;
-            final long interval2 = b2.end - b2.start;
-            if (interval1 > interval2) {
-                return 1;
-            }
-            if (interval2 < interval1) {
-                return -1;
-            }
-
-            // equal start + delivery window => they're identical
             return 0;
         }
     }
@@ -615,7 +597,7 @@
     @Override
     public void onStart() {
         mNativeData = init();
-        mNextWakeup = mNextWakeupBatchStart = mNextNonWakeup = 0;
+        mNextWakeup = mNextNonWakeup = 0;
 
         // We have to set current TimeZone info to kernel
         // because kernel doesn't keep this after reboot
@@ -823,7 +805,6 @@
                         "AlarmManager.set");
             }
 
-            // Exact alarms are standalone; inexact get batched together
             setImpl(type, triggerAtTime, windowLength, interval, operation,
                     windowLength == AlarmManager.WINDOW_EXACT, workSource, alarmClock);
         }
@@ -896,7 +877,7 @@
 
             pw.print("nowRTC="); pw.print(nowRTC);
             pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
-            pw.print(" nowELAPSED="); pw.print(nowELAPSED);
+            pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw);
             pw.println();
             if (!mInteractive) {
                 pw.print("Time since non-interactive: ");
@@ -1102,6 +1083,17 @@
         return true;
     }
 
+    private Batch findFirstWakeupBatchLocked() {
+        final int N = mAlarmBatches.size();
+        for (int i = 0; i < N; i++) {
+            Batch b = mAlarmBatches.get(i);
+            if (b.hasWakeups()) {
+                return b;
+            }
+        }
+        return null;
+    }
+
     private AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
         synchronized (mLock) {
             return mNextAlarmClockForUser.get(userId);
@@ -1236,48 +1228,16 @@
         // prior to that which contains no wakeups, we schedule that as well.
         long nextNonWakeup = 0;
         if (mAlarmBatches.size() > 0) {
-            // Find the first wakeup alarm and note the following batch as well.  We'll be
-            // choosing a fuzzed delivery time within the first's allowable interval but
-            // ensuring that it does not encroach on the second's start time, to minimize
-            // alarm reordering.
-            Batch firstWakeup = null, nextAfterWakeup = null;
-            final int N = mAlarmBatches.size();
-            for (int i = 0; i < N; i++) {
-                Batch b = mAlarmBatches.get(i);
-                if (b.hasWakeups()) {
-                    firstWakeup = b;
-                    if (i < N-1) {
-                        nextAfterWakeup = mAlarmBatches.get(i+1);
-                    }
-                    break;
-                }
-            }
-
-            // There's a subtlety here: we depend on the invariant that if two batches
-            // exist with the same start time, the one with the shorter delivery window
-            // is sorted before the other.  This guarantees us that we need only look
-            // at the first [relevant] batch in the queue in order to schedule an alarm
-            // appropriately.
+            final Batch firstWakeup = findFirstWakeupBatchLocked();
             final Batch firstBatch = mAlarmBatches.get(0);
-            if (firstWakeup != null && mNextWakeupBatchStart != firstWakeup.start) {
-                mNextWakeupBatchStart = mNextWakeup = firstWakeup.start;
-                final long windowEnd = (nextAfterWakeup == null)
-                        ? firstWakeup.end
-                        : Math.min(firstWakeup.end, nextAfterWakeup.start);
-                final long interval = windowEnd - firstWakeup.start;
-                // if the interval is over maxint we're into crazy land anyway, but
-                // just in case we check and don't fuzz if the conversion to int for
-                // random-number purposes would blow up
-                if (interval > 0 && interval < Integer.MAX_VALUE) {
-                    mNextWakeup += mFuzzer.nextInt((int) interval);
-                }
-                setLocked(ELAPSED_REALTIME_WAKEUP, mNextWakeup);
+            if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
+                mNextWakeup = firstWakeup.start;
+                setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
             }
             if (firstBatch != firstWakeup) {
                 nextNonWakeup = firstBatch.start;
             }
         }
-
         if (mPendingNonWakeupAlarms.size() > 0) {
             if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) {
                 nextNonWakeup = mNextNonWakeupDeliveryTime;
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index fc4838c..bc31450 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -46,8 +46,11 @@
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -66,7 +69,7 @@
      */
     public static final String ASSET_ATLAS_SERVICE = "assetatlas";
 
-    private static final String LOG_TAG = "Atlas";
+    private static final String LOG_TAG = "AssetAtlas";
 
     // Turns debug logs on/off. Debug logs are kept to a minimum and should
     // remain on to diagnose issues
@@ -131,7 +134,7 @@
         mContext = context;
         mVersionName = queryVersionName(context);
 
-        ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(300);
+        Collection<Bitmap> bitmaps = new HashSet<Bitmap>(300);
         int totalPixelCount = 0;
 
         // We only care about drawables that hold bitmaps
@@ -140,16 +143,18 @@
 
         final int count = drawables.size();
         for (int i = 0; i < count; i++) {
-            final Bitmap bitmap = drawables.valueAt(i).getBitmap();
-            if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
-                bitmaps.add(bitmap);
-                totalPixelCount += bitmap.getWidth() * bitmap.getHeight();
+            try {
+                totalPixelCount += drawables.valueAt(i).addAtlasableBitmaps(bitmaps);
+            } catch (Throwable t) {
+                Log.e("AssetAtlas", "Failed to fetch preloaded drawable state", t);
+                throw t;
             }
         }
 
+        ArrayList<Bitmap> sortedBitmaps = new ArrayList<Bitmap>(bitmaps);
         // Our algorithms perform better when the bitmaps are first sorted
         // The comparator will sort the bitmap by width first, then by height
-        Collections.sort(bitmaps, new Comparator<Bitmap>() {
+        Collections.sort(sortedBitmaps, new Comparator<Bitmap>() {
             @Override
             public int compare(Bitmap b1, Bitmap b2) {
                 if (b1.getWidth() == b2.getWidth()) {
@@ -160,7 +165,7 @@
         });
 
         // Kick off the packing work on a worker thread
-        new Thread(new Renderer(bitmaps, totalPixelCount)).start();
+        new Thread(new Renderer(sortedBitmaps, totalPixelCount)).start();
     }
 
     /**
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 3117a17..ca376fd 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -535,15 +535,14 @@
                     Log.d(TAG, "Creating new ProfileServiceConnections object for"
                             + " profile: " + bluetoothProfile);
                 }
-                Intent intent = null;
-                if (bluetoothProfile == BluetoothProfile.HEADSET) {
-                    intent = new Intent(IBluetoothHeadset.class.getName());
-                } else {
-                    return false;
-                }
+
+                if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
+
+                Intent intent = new Intent(IBluetoothHeadset.class.getName());
                 psc = new ProfileServiceConnections(intent);
+                if (!psc.bindService()) return false;
+
                 mProfileServices.put(new Integer(bluetoothProfile), psc);
-                psc.bindService();
             }
         }
 
@@ -571,7 +570,11 @@
         synchronized (mProfileServices) {
             for (Integer i : mProfileServices.keySet()) {
                 ProfileServiceConnections psc = mProfileServices.get(i);
-                mContext.unbindService(psc);
+                try {
+                    mContext.unbindService(psc);
+                } catch (IllegalArgumentException e) {
+                    Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
+                }
                 psc.removeAllProxies();
             }
             mProfileServices.clear();
@@ -596,16 +599,16 @@
             mIntent = intent;
         }
 
-        private void bindService() {
-            if (mIntent != null && mService == null) {
-                if (!doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
-                    Log.w(TAG, "Unable to bind with intent: " + mIntent
-                            + ". Triggering retry.");
-                }
+        private boolean bindService() {
+            if (mIntent != null && mService == null &&
+                    doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
                 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
                 msg.obj = this;
                 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
+                return true;
             }
+            Log.w(TAG, "Unable to bind with intent: " + mIntent);
+            return false;
         }
 
         private void addProxy(IBluetoothProfileServiceConnection proxy) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a86d564..788b5d3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -782,17 +782,6 @@
         throw new IllegalStateException("No free netIds");
     }
 
-    private int getConnectivityChangeDelay() {
-        final ContentResolver cr = mContext.getContentResolver();
-
-        /** Check system properties for the default value then use secure settings value, if any. */
-        int defaultDelay = SystemProperties.getInt(
-                "conn." + Settings.Global.CONNECTIVITY_CHANGE_DELAY,
-                ConnectivityManager.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
-        return Settings.Global.getInt(cr, Settings.Global.CONNECTIVITY_CHANGE_DELAY,
-                defaultDelay);
-    }
-
     private boolean teardown(NetworkStateTracker netTracker) {
         if (netTracker.teardown()) {
             netTracker.setTeardownRequested(true);
@@ -1454,11 +1443,6 @@
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
 
-    private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
-        sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
-        sendGeneralBroadcastDelayed(info, CONNECTIVITY_ACTION, delayMs);
-    }
-
     private void sendInetConditionBroadcast(NetworkInfo info) {
         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
     }
@@ -1490,10 +1474,6 @@
         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
     }
 
-    private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
-        sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
-    }
-
     private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
         Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
         intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
@@ -1538,19 +1518,6 @@
         }
     }
 
-    private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
-        if (delayMs <= 0) {
-            sendStickyBroadcast(intent);
-        } else {
-            if (VDBG) {
-                log("sendStickyBroadcastDelayed: delayMs=" + delayMs + ", action="
-                        + intent.getAction());
-            }
-            mHandler.sendMessageDelayed(mHandler.obtainMessage(
-                    EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
-        }
-    }
-
     void systemReady() {
         // start network sampling ..
         Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
@@ -2618,7 +2585,7 @@
         }
     }
 
-    public ProxyInfo getProxy() {
+    public ProxyInfo getDefaultProxy() {
         // this information is already available as a world read/writable jvm property
         // so this API change wouldn't have a benifit.  It also breaks the passing
         // of proxy info to all the JVMs.
@@ -2630,6 +2597,34 @@
         }
     }
 
+    // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
+    // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
+    // proxy is null then there is no proxy in place).
+    private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) {
+        if (proxy != null && TextUtils.isEmpty(proxy.getHost())
+                && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
+            proxy = null;
+        }
+        return proxy;
+    }
+
+    // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it
+    // better for determining if a new proxy broadcast is necessary:
+    // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
+    //    avoid unnecessary broadcasts.
+    // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
+    //    is in place.  This is important so legacy PAC resolver (see com.android.proxyhandler)
+    //    changes aren't missed.  The legacy PAC resolver pretends to be a simple HTTP proxy but
+    //    actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
+    //    all set.
+    private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) {
+        a = canonicalizeProxyInfo(a);
+        b = canonicalizeProxyInfo(b);
+        // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
+        // hosts even when PAC URLs are present to account for the legacy PAC resolver.
+        return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost()));
+    }
+
     public void setGlobalProxy(ProxyInfo proxyProperties) {
         enforceConnectivityInternalPermission();
 
@@ -2747,6 +2742,20 @@
         }
     }
 
+    // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
+    // This method gets called when any network changes proxy, but the broadcast only ever contains
+    // the default proxy (even if it hasn't changed).
+    // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network
+    // world where an app might be bound to a non-default network.
+    private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
+        ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
+        ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
+
+        if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
+            sendProxyBroadcast(getDefaultProxy());
+        }
+    }
+
     private void handleDeprecatedGlobalHttpProxy() {
         String proxy = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.HTTP_PROXY);
@@ -3660,7 +3669,11 @@
         updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns);
 
         updateClat(newLp, oldLp, networkAgent);
-        if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy());
+        if (isDefaultNetwork(networkAgent)) {
+            handleApplyDefaultProxy(newLp.getHttpProxy());
+        } else {
+            updateProxy(newLp, oldLp, networkAgent);
+        }
         // TODO - move this check to cover the whole function
         if (!Objects.equals(newLp, oldLp)) {
             notifyIfacesChanged();
@@ -3936,6 +3949,7 @@
         notifyLockdownVpn(newNetwork);
         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
         updateTcpBufferSizes(newNetwork);
+        setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
     }
 
     // Handles a network appearing or improving its score.
@@ -3975,6 +3989,7 @@
         }
         boolean keep = newNetwork.isVPN();
         boolean isNewDefault = false;
+        NetworkAgentInfo oldDefaultNetwork = null;
         if (DBG) log("rematching " + newNetwork.name());
         // Find and migrate to this Network any NetworkRequests for
         // which this network is now the best.
@@ -4032,25 +4047,7 @@
                     sendUpdatedScoreToFactories(nri.request, newNetwork.getCurrentScore());
                     if (mDefaultRequest.requestId == nri.request.requestId) {
                         isNewDefault = true;
-                        // TODO: Remove following line.  It's redundant with makeDefault call.
-                        if (newNetwork.linkProperties != null) {
-                            updateTcpBufferSizes(newNetwork);
-                            setDefaultDnsSystemProperties(
-                                    newNetwork.linkProperties.getDnsServers());
-                        } else {
-                            setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
-                        }
-                        // Maintain the illusion: since the legacy API only
-                        // understands one network at a time, we must pretend
-                        // that the current default network disconnected before
-                        // the new one connected.
-                        if (currentNetwork != null) {
-                            mLegacyTypeTracker.remove(currentNetwork.networkInfo.getType(),
-                                                      currentNetwork);
-                        }
-                        mDefaultInetConditionPublished = newNetwork.validated ? 100 : 0;
-                        mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
-                        notifyLockdownVpn(newNetwork);
+                        oldDefaultNetwork = currentNetwork;
                     }
                 }
             }
@@ -4091,6 +4088,17 @@
                                 1000);
                     }
                 }
+                // Maintain the illusion: since the legacy API only
+                // understands one network at a time, we must pretend
+                // that the current default network disconnected before
+                // the new one connected.
+                if (oldDefaultNetwork != null) {
+                    mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
+                                              oldDefaultNetwork);
+                }
+                mDefaultInetConditionPublished = newNetwork.validated ? 100 : 0;
+                mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
+                notifyLockdownVpn(newNetwork);
             }
 
             // Notify battery stats service about this network, both the normal
@@ -4331,7 +4339,7 @@
         info.setType(type);
         if (connected) {
             info.setDetailedState(DetailedState.CONNECTED, null, info.getExtraInfo());
-            sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
+            sendConnectedBroadcast(info);
         } else {
             info.setDetailedState(DetailedState.DISCONNECTED, null, info.getExtraInfo());
             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
@@ -4362,10 +4370,9 @@
             final Intent immediateIntent = new Intent(intent);
             immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
             sendStickyBroadcast(immediateIntent);
-            sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
+            sendStickyBroadcast(intent);
             if (newDefaultAgent != null) {
-                sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
-                getConnectivityChangeDelay());
+                sendConnectedBroadcast(newDefaultAgent.networkInfo);
             }
         }
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 34da901..776f836 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -480,7 +480,7 @@
                 r.callerUid = callerUid;
                 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
                 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
-                if (!SubscriptionManager.isValidSubId(subId)) {
+                if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                     r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
                  } else {//APP specify subID
                     r.subId = subId;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0373611..c0fc890 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1841,7 +1841,9 @@
                         proc = mPendingPssProcesses.remove(0);
                         procState = proc.pssProcState;
                         lastPssTime = proc.lastPssTime;
-                        if (proc.thread != null && procState == proc.setProcState) {
+                        if (proc.thread != null && procState == proc.setProcState
+                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
+                                        < SystemClock.uptimeMillis()) {
                             pid = proc.pid;
                         } else {
                             proc = null;
@@ -4655,9 +4657,11 @@
             stats.noteProcessDiedLocked(app.info.uid, pid);
         }
 
-        Process.killProcessQuiet(pid);
-        Process.killProcessGroup(app.info.uid, pid);
-        app.killed = true;
+        if (!app.killed) {
+            Process.killProcessQuiet(pid);
+            Process.killProcessGroup(app.info.uid, pid);
+            app.killed = true;
+        }
 
         // Clean up already done if the process has been re-started.
         if (app.pid == pid && app.thread != null &&
@@ -15700,11 +15704,13 @@
                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
 
         // Make sure that the user who is receiving this broadcast is running.
-        // If not, we will just skip it.
+        // If not, we will just skip it. Make an exception for shutdown broadcasts
+        // and upgrade steps.
 
         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
-            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
-                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
+            if ((callingUid != Process.SYSTEM_UID
+                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
+                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
                 Slog.w(TAG, "Skipping broadcast of " + intent
                         + ": user " + userId + " is stopped");
                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
@@ -17744,7 +17750,8 @@
                     + (app.nextPssTime-now) + ": " + app);
         } else {
             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
-                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
+                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
+                    mTestPssMode)))) {
                 requestPssLocked(app, app.setProcState);
                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
                         mTestPssMode, isSleeping(), now);
@@ -18967,6 +18974,31 @@
             }
             mUserSwitchObservers.finishBroadcast();
         }
+        stopGuestUserIfBackground();
+    }
+
+    /**
+     * Stops the guest user if it has gone to the background.
+     */
+    private void stopGuestUserIfBackground() {
+        synchronized (this) {
+            final int num = mUserLru.size();
+            for (int i = 0; i < num; i++) {
+                Integer oldUserId = mUserLru.get(i);
+                UserStartedState oldUss = mStartedUsers.get(oldUserId);
+                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
+                        || oldUss.mState == UserStartedState.STATE_STOPPING
+                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+                    continue;
+                }
+                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
+                if (userInfo.isGuest()) {
+                    // This is a user to be stopped.
+                    stopUserLocked(oldUserId, null);
+                    break;
+                }
+            }
+        }
     }
 
     void scheduleStartProfilesLocked() {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index d98f03c..efed0b9 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -222,13 +222,6 @@
     long mLaunchStartTime = 0;
     long mFullyDrawnStartTime = 0;
 
-    /**
-     * Save the most recent screenshot for reuse. This keeps Recents from taking two identical
-     * screenshots, one for the Recents thumbnail and one for the pauseActivity thumbnail.
-     */
-    private ActivityRecord mLastScreenshotActivity = null;
-    private Bitmap mLastScreenshotBitmap = null;
-
     int mCurrentUser;
 
     final int mStackId;
@@ -741,18 +734,6 @@
         }
     }
 
-    /**
-     * This resets the saved state from the last screenshot, forcing a new screenshot to be taken
-     * again when requested.
-     */
-    private void invalidateLastScreenshot() {
-        mLastScreenshotActivity = null;
-        if (mLastScreenshotBitmap != null) {
-            mLastScreenshotBitmap.recycle();
-        }
-        mLastScreenshotBitmap = null;
-    }
-
     public final Bitmap screenshotActivities(ActivityRecord who) {
         if (DEBUG_SCREENSHOTS) Slog.d(TAG, "screenshotActivities: " + who);
         if (who.noDisplay) {
@@ -762,30 +743,17 @@
 
         if (isHomeStack()) {
             // This is an optimization -- since we never show Home or Recents within Recents itself,
-            // we can just go ahead and skip taking the screenshot if this is the home stack.  In
-            // the case where the most recent task is not the task that was supplied, then the stack
-            // has changed, so invalidate the last screenshot().
-            invalidateLastScreenshot();
-            if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tIs Home stack? " + isHomeStack());
+            // we can just go ahead and skip taking the screenshot if this is the home stack.
+            if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tHome stack");
             return null;
         }
 
         int w = mService.mThumbnailWidth;
         int h = mService.mThumbnailHeight;
         if (w > 0) {
-            if (who != mLastScreenshotActivity || mLastScreenshotBitmap == null
-                    || mLastScreenshotActivity.state == ActivityState.RESUMED
-                    || mLastScreenshotBitmap.getWidth() != w
-                    || mLastScreenshotBitmap.getHeight() != h) {
-                if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tUpdating screenshot");
-                mLastScreenshotActivity = who;
-                mLastScreenshotBitmap = mWindowManager.screenshotApplications(
-                        who.appToken, Display.DEFAULT_DISPLAY, w, h, SCREENSHOT_FORCE_565);
-            }
-            if (mLastScreenshotBitmap != null) {
-                if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tReusing last screenshot");
-                return mLastScreenshotBitmap.copy(mLastScreenshotBitmap.getConfig(), true);
-            }
+            if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tTaking screenshot");
+            return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
+                    w, h, SCREENSHOT_FORCE_565);
         }
         Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h);
         return null;
@@ -1103,11 +1071,6 @@
             next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
         }
 
-        // If we are resuming the activity that we had last screenshotted, then we know it will be
-        // updated, so invalidate the last screenshot to ensure we take a fresh one when requested
-        if (next == mLastScreenshotActivity) {
-            invalidateLastScreenshot();
-        }
         next.returningOptions = null;
 
         if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == next) {
@@ -1824,9 +1787,6 @@
                     // Do over!
                     mStackSupervisor.scheduleResumeTopActivities();
                 }
-                if (next == mLastScreenshotActivity) {
-                    invalidateLastScreenshot();
-                }
                 if (mStackSupervisor.reportResumedActivityLocked(next)) {
                     mNoAnimActivities.clear();
                     if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index aa86786..ae4af5f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -238,7 +238,7 @@
         if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
             // Increase the high min-free levels for cached processes for 64-bit
             mOomMinFreeHigh[4] = (mOomMinFreeHigh[4]*3)/2;
-            mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/8;
+            mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/4;
         }
 
         for (int i=0; i<mOomAdj.length; i++) {
@@ -411,7 +411,10 @@
         sb.append(ramKb);
     }
 
-    // The minimum amount of time after a state change it is safe ro collect PSS.
+    // How long after a state change that it is safe to collect PSS without it being dirty.
+    public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
+
+    // The minimum time interval after a state change it is safe to collect PSS.
     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
 
     // The maximum amount of time we want to go between PSS collections.
@@ -441,6 +444,9 @@
     // The amount of time until PSS when a cached process stays in the same state.
     private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
 
+    // The minimum time interval after a state change it is safe to collect PSS.
+    public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
+
     // The amount of time during testing until PSS when a process first becomes top.
     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
 
@@ -548,6 +554,10 @@
         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
     }
 
+    public static long minTimeFromStateChange(boolean test) {
+        return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
+    }
+
     public static long computeNextPssTime(int procState, boolean first, boolean test,
             boolean sleeping, long now) {
         final long[] table = test
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bb99916..650f0e2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1028,6 +1028,7 @@
                 ? mListenersDisablingEffects.valueAt(0).component : null;
         if (Objects.equals(suppressor, mEffectsSuppressor)) return;
         mEffectsSuppressor = suppressor;
+        mZenModeHelper.setEffectsSuppressed(suppressor != null);
         getContext().sendBroadcast(new Intent(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)
                 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 012e22f..0f9a59b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -17,6 +17,7 @@
 package com.android.server.notification;
 
 import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 
 import android.app.AppOpsManager;
@@ -77,6 +78,7 @@
     private ZenModeConfig mConfig;
     private AudioManagerInternal mAudioManager;
     private int mPreviousRingerMode = -1;
+    private boolean mEffectsSuppressed;
 
     public ZenModeHelper(Context context, Looper looper) {
         mContext = context;
@@ -153,6 +155,12 @@
         }
     }
 
+    public void setEffectsSuppressed(boolean effectsSuppressed) {
+        if (mEffectsSuppressed == effectsSuppressed) return;
+        mEffectsSuppressed = effectsSuppressed;
+        applyRestrictions();
+    }
+
     public boolean shouldIntercept(NotificationRecord record) {
         if (isSystem(record)) {
             return false;
@@ -225,29 +233,35 @@
             ZenLog.traceUpdateZenMode(oldMode, newMode);
         }
         mZenMode = newMode;
+        applyRestrictions();
+        onZenUpdated(oldMode, newMode);
+        dispatchOnZenModeChanged();
+    }
+
+    private void applyRestrictions() {
         final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
-        final String[] exceptionPackages = null; // none (for now)
+
+        // notification restrictions
+        final boolean muteNotifications = mEffectsSuppressed;
+        applyRestrictions(muteNotifications, USAGE_NOTIFICATION);
 
         // call restrictions
-        final boolean muteCalls = zen && !mConfig.allowCalls;
-        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_NOTIFICATION_RINGTONE,
-                muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
-                exceptionPackages);
-        mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_NOTIFICATION_RINGTONE,
-                muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
-                exceptionPackages);
+        final boolean muteCalls = zen && !mConfig.allowCalls || mEffectsSuppressed;
+        applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
 
         // alarm restrictions
         final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM,
-                muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
-                exceptionPackages);
-        mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_ALARM,
-                muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
-                exceptionPackages);
+        applyRestrictions(muteAlarms, USAGE_ALARM);
+    }
 
-        onZenUpdated(oldMode, newMode);
-        dispatchOnZenModeChanged();
+    private void applyRestrictions(boolean mute, int usage) {
+        final String[] exceptionPackages = null; // none (for now)
+        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage,
+                mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+        mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, usage,
+                mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
     }
 
     public void dump(PrintWriter pw, String prefix) {
@@ -257,6 +271,7 @@
         pw.print(prefix); pw.print("mDefaultConfig="); pw.println(mDefaultConfig);
         pw.print(prefix); pw.print("mPreviousRingerMode="); pw.println(mPreviousRingerMode);
         pw.print(prefix); pw.print("mDefaultPhoneApp="); pw.println(mDefaultPhoneApp);
+        pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
     }
 
     public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException {
@@ -332,7 +347,10 @@
                 break;
             case AudioManager.RINGER_MODE_VIBRATE:
             case AudioManager.RINGER_MODE_NORMAL:
-                if (mZenMode != Global.ZEN_MODE_OFF) {
+                if (isChange && ringerModeOld == AudioManager.RINGER_MODE_SILENT
+                        && mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+                    newZen = Global.ZEN_MODE_OFF;
+                } else if (mZenMode != Global.ZEN_MODE_OFF) {
                     ringerModeExternalOut = AudioManager.RINGER_MODE_SILENT;
                 }
                 break;
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index cb9a45e..7e66cd1 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -39,6 +39,11 @@
             "android",
             BackgroundDexOptService.class.getName());
 
+    /**
+     * Set of failed packages remembered across job runs.
+     */
+    static final ArraySet<String> sFailedPackageNames = new ArraySet<String>();
+
     final AtomicBoolean mIdleTime = new AtomicBoolean(false);
 
     public static void schedule(Context context) {
@@ -75,7 +80,15 @@
                         schedule(BackgroundDexOptService.this);
                         return;
                     }
-                    pm.performDexOpt(pkg, null /* instruction set */, true);
+                    if (sFailedPackageNames.contains(pkg)) {
+                        // skip previously failing package
+                        continue;
+                    }
+                    if (!pm.performDexOpt(pkg, null /* instruction set */, true)) {
+                        // there was a problem running dexopt,
+                        // remember this so we do not keep retrying.
+                        sFailedPackageNames.add(pkg);
+                    }
                 }
                 // ran to completion, so we abandon our timeslice and do not reschedule
                 jobFinished(jobParams, false);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6f1e851..91637e3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10199,13 +10199,13 @@
                 // default to original signature matching
                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
                     != PackageManager.SIGNATURE_MATCH) {
-                    res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                             "New package has a different signature: " + pkgName);
                     return;
                 }
             } else {
                 if(!checkUpgradeKeySetLP(ps, pkg)) {
-                    res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                             "New package not signed by keys specified by upgrade-keysets: "
                             + pkgName);
                     return;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 257cbd0..bd2e923 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -116,6 +116,7 @@
         final WallpaperData mWallpaper;
         final File mWallpaperDir;
         final File mWallpaperFile;
+        final File mWallpaperInfoFile;
 
         public WallpaperObserver(WallpaperData wallpaper) {
             super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
@@ -123,6 +124,7 @@
             mWallpaperDir = getWallpaperDir(wallpaper.userId);
             mWallpaper = wallpaper;
             mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
+            mWallpaperInfoFile = new File(mWallpaperDir, WALLPAPER_INFO);
         }
 
         @Override
@@ -131,13 +133,15 @@
                 return;
             }
             synchronized (mLock) {
-                // changing the wallpaper means we'll need to back up the new one
-                long origId = Binder.clearCallingIdentity();
-                BackupManager bm = new BackupManager(mContext);
-                bm.dataChanged();
-                Binder.restoreCallingIdentity(origId);
-
                 File changedFile = new File(mWallpaperDir, path);
+                if (mWallpaperFile.equals(changedFile)
+                        || mWallpaperInfoFile.equals(changedFile)) {
+                    // changing the wallpaper means we'll need to back up the new one
+                    long origId = Binder.clearCallingIdentity();
+                    BackupManager bm = new BackupManager(mContext);
+                    bm.dataChanged();
+                    Binder.restoreCallingIdentity(origId);
+                }
                 if (mWallpaperFile.equals(changedFile)) {
                     notifyCallbacksLocked(mWallpaper);
                     final boolean written = (event == CLOSE_WRITE || event == MOVED_TO);
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index c1420a8..37d811f 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -68,9 +68,18 @@
                 break;
 
             case KEYGUARD_POLICY_CHANGED:
-                mPolicy.enableKeyguard(true);
-                // lazily evaluate this next time we're asked to disable keyguard
                 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
+                if (mKeyguardTokenWatcher.isAcquired()) {
+                    // If we are currently disabled we need to know if the keyguard
+                    // should be re-enabled, so determine the allow state immediately.
+                    mKeyguardTokenWatcher.updateAllowState();
+                    if (mAllowDisableKeyguard != ALLOW_DISABLE_YES) {
+                        mPolicy.enableKeyguard(true);
+                    }
+                } else {
+                    // lazily evaluate this next time we're asked to disable keyguard
+                    mPolicy.enableKeyguard(true);
+                }
                 break;
         }
     }
@@ -81,24 +90,28 @@
             super(handler, TAG);
         }
 
-        @Override
-        public void acquired() {
+        public void updateAllowState() {
             // We fail safe and prevent disabling keyguard in the unlikely event this gets
             // called before DevicePolicyManagerService has started.
-            if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
-                DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
-                        Context.DEVICE_POLICY_SERVICE);
-                if (dpm != null) {
-                    try {
-                        mAllowDisableKeyguard = dpm.getPasswordQuality(null, 
-                                ActivityManagerNative.getDefault().getCurrentUser().id)
-                                == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
-                                        ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
-                    } catch (RemoteException re) {
-                        // Nothing much we can do
-                    }
+            DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            if (dpm != null) {
+                try {
+                    mAllowDisableKeyguard = dpm.getPasswordQuality(null,
+                            ActivityManagerNative.getDefault().getCurrentUser().id)
+                            == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
+                                    ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
+                } catch (RemoteException re) {
+                    // Nothing much we can do
                 }
             }
+        }
+
+        @Override
+        public void acquired() {
+            if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
+                updateAllowState();
+            }
             if (mAllowDisableKeyguard == ALLOW_DISABLE_YES) {
                 mPolicy.enableKeyguard(false);
             } else {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fe2e0a6..64713d9 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -355,7 +355,8 @@
                         boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
                                 && !winAnimator.mKeyguardGoingAwayAnimation
                                 && win.hasDrawnLw()
-                                && win.mAttachedWindow == null;
+                                && win.mAttachedWindow == null
+                                && mForceHiding != KEYGUARD_NOT_SHOWN;
 
                         // If the window is already showing and we don't need to apply an existing
                         // Keyguard exit animation, skip.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ba89f23..021a6e4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -617,8 +617,8 @@
 
         mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
                 Math.max(mOverscanFrame.top - mFrame.top, 0),
-                Math.min(mFrame.right - mOverscanFrame.right, 0),
-                Math.min(mFrame.bottom - mOverscanFrame.bottom, 0));
+                Math.max(mFrame.right - mOverscanFrame.right, 0),
+                Math.max(mFrame.bottom - mOverscanFrame.bottom, 0));
 
         mContentInsets.set(mContentFrame.left - mFrame.left,
                 mContentFrame.top - mFrame.top,
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index f3b0586..a180f44 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -246,6 +246,7 @@
         public void onVideoStateChanged(Connection c, int videoState) {}
         public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
         public void onPostDialWait(Connection c, String remaining) {}
+        public void onPostDialChar(Connection c, char nextChar) {}
         public void onRingbackRequested(Connection c, boolean ringback) {}
         public void onDestroyed(Connection c) {}
         public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
@@ -998,6 +999,23 @@
     }
 
     /**
+     * Informs listeners that this {@code Connection} has processed a character in the post-dial
+     * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
+     * (b) it has encountered a "wait" character; and (c) it wishes to signal Telecom to play
+     * the corresponding DTMF tone locally.
+     *
+     * @param nextChar The DTMF character that was just processed by the {@code Connection}.
+     *
+     * @hide
+     */
+    public final void setNextPostDialWaitChar(char nextChar) {
+        checkImmutable();
+        for (Listener l : mListeners) {
+            l.onPostDialChar(this, nextChar);
+        }
+    }
+
+    /**
      * Requests that the framework play a ringback tone. This is to be invoked by implementations
      * that do not play a ringback tone themselves in the connection's audio stream.
      *
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index d0a8aee..df16375 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -484,6 +484,13 @@
         }
 
         @Override
+        public void onPostDialChar(Connection c, char nextChar) {
+            String id = mIdByConnection.get(c);
+            Log.d(this, "Adapter onPostDialChar %s, %s", c, nextChar);
+            mAdapter.onPostDialChar(id, nextChar);
+        }
+
+        @Override
         public void onRingbackRequested(Connection c, boolean ringback) {
             String id = mIdByConnection.get(c);
             Log.d(this, "Adapter onRingback %b", ringback);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index aee9675..d026a28 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -226,6 +226,15 @@
         }
     }
 
+    void onPostDialChar(String callId, char nextChar) {
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                adapter.onPostDialChar(callId, nextChar);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     /**
      * Indicates that a new conference call has been created.
      *
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 7619da5..429f296 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -58,6 +58,7 @@
     private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
     private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
     private static final int MSG_ADD_EXISTING_CONNECTION = 21;
+    private static final int MSG_ON_POST_DIAL_CHAR = 22;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -143,6 +144,15 @@
                     }
                     break;
                 }
+                case MSG_ON_POST_DIAL_CHAR: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.onPostDialChar((String) args.arg1, (char) args.argi1);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 case MSG_QUERY_REMOTE_CALL_SERVICES:
                     mDelegate.queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
                     break;
@@ -299,6 +309,14 @@
         }
 
         @Override
+        public void onPostDialChar(String connectionId, char nextChar) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.argi1 = nextChar;
+            mHandler.obtainMessage(MSG_ON_POST_DIAL_CHAR, args).sendToTarget();
+        }
+
+        @Override
         public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
             mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
         }
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 95cc387..486691f 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -101,6 +101,15 @@
         public void onPostDialWait(RemoteConnection connection, String remainingPostDialSequence) {}
 
         /**
+         * Invoked when the post-dial sequence in the outgoing {@code Connection} has processed
+         * a character.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param nextChar The character being processed.
+         */
+        public void onPostDialChar(RemoteConnection connection, char nextChar) {}
+
+        /**
          * Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
          * See {@link #isVoipAudioMode()}.
          *
@@ -726,7 +735,7 @@
      * of time.
      *
      * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, this
-     * {@code RemoteConnection} will pause playing the tones and notify callbackss via
+     * {@code RemoteConnection} will pause playing the tones and notify callbacks via
      * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
      * should display to the user an indication of this state and an affordance to continue
      * the postdial sequence. When the user decides to continue the postdial sequence, the in-call
@@ -869,6 +878,15 @@
     /**
      * @hide
      */
+    void onPostDialChar(char nextChar) {
+        for (Callback c : mCallbacks) {
+            c.onPostDialChar(this, nextChar);
+        }
+    }
+
+    /**
+     * @hide
+     */
     void setVideoState(int videoState) {
         mVideoState = videoState;
         for (Callback c : mCallbacks) {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 906ecaa..073dcd5f 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -223,6 +223,12 @@
         }
 
         @Override
+        public void onPostDialChar(String callId, char nextChar) {
+            findConnectionForAction(callId, "onPostDialChar")
+                    .onPostDialChar(nextChar);
+        }
+
+        @Override
         public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
             // Not supported from remote connection service.
         }
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 4517a96..7e7e9cc 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -62,6 +62,8 @@
 
     void onPostDialWait(String callId, String remaining);
 
+    void onPostDialChar(String callId, char nextChar);
+
     void queryRemoteConnectionServices(RemoteServiceCallback callback);
 
     void setVideoProvider(String callId, IVideoProvider videoProvider);
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 0844232..4ff6389 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1823,13 +1823,11 @@
         String emergencyNumbers = "";
         int slotId = SubscriptionManager.getSlotId(subId);
 
-        if (slotId >= 0) {
-            // retrieve the list of emergency numbers
-            // check read-write ecclist property first
-            String ecclist = (slotId == 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
+        // retrieve the list of emergency numbers
+        // check read-write ecclist property first
+        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
 
-            emergencyNumbers = SystemProperties.get(ecclist, "");
-        }
+        emergencyNumbers = SystemProperties.get(ecclist, "");
 
         Rlog.d(LOG_TAG, "slotId:" + slotId + ", emergencyNumbers: " +  emergencyNumbers);
 
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 20cd037..d174f47 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -52,6 +52,7 @@
     private static final boolean VDBG = false;
 
     /** An invalid subscription identifier */
+    /** @hide */
     public static final int INVALID_SUBSCRIPTION_ID = -1;
 
     /** Base value for Dummy SUBSCRIPTION_ID's. */
@@ -391,7 +392,7 @@
      */
     public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
         if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
-        if (!isValidSubId(subId)) {
+        if (!isValidSubscriptionId(subId)) {
             logd("[getActiveSubscriptionInfo]- invalid subId");
             return null;
         }
@@ -625,7 +626,7 @@
      */
     public int setIconTint(int tint, int subId) {
         if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
-        if (!isValidSubId(subId)) {
+        if (!isValidSubscriptionId(subId)) {
             logd("[setIconTint]- fail");
             return -1;
         }
@@ -662,7 +663,7 @@
      * @param subId the unique SubscriptionInfo index in database
      * @param nameSource 0: NAME_SOURCE_DEFAULT_SOURCE, 1: NAME_SOURCE_SIM_SOURCE,
      *                   2: NAME_SOURCE_USER_INPUT, -1 NAME_SOURCE_UNDEFINED
-     * @return the number of records updated or -1 if invalid subId
+     * @return the number of records updated or < 0 if invalid subId
      * @hide
      */
     public int setDisplayName(String displayName, int subId, long nameSource) {
@@ -670,7 +671,7 @@
             logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
                     + " nameSource:" + nameSource);
         }
-        if (!isValidSubId(subId)) {
+        if (!isValidSubscriptionId(subId)) {
             logd("[setDisplayName]- fail");
             return -1;
         }
@@ -698,7 +699,7 @@
      * @hide
      */
     public int setDisplayNumber(String number, int subId) {
-        if (number == null || !isValidSubId(subId)) {
+        if (number == null || !isValidSubscriptionId(subId)) {
             logd("[setDisplayNumber]- fail");
             return -1;
         }
@@ -727,7 +728,7 @@
      */
     public int setDataRoaming(int roaming, int subId) {
         if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
-        if (roaming < 0 || !isValidSubId(subId)) {
+        if (roaming < 0 || !isValidSubscriptionId(subId)) {
             logd("[setDataRoaming]- fail");
             return -1;
         }
@@ -749,11 +750,11 @@
     /**
      * Get slotId associated with the subscription.
      * @return slotId as a positive integer or a negative value if an error either
-     * SIM_NOT_INSERTED or INVALID_SLOT_ID.
+     * SIM_NOT_INSERTED or < 0 if an invalid slot index
      * @hide
      */
     public static int getSlotId(int subId) {
-        if (!isValidSubId(subId)) {
+        if (!isValidSubscriptionId(subId)) {
             logd("[getSlotId]- fail");
         }
 
@@ -795,7 +796,7 @@
 
     /** @hide */
     public static int getPhoneId(int subId) {
-        if (!isValidSubId(subId)) {
+        if (!isValidSubscriptionId(subId)) {
             logd("[getPhoneId]- fail");
             return INVALID_PHONE_INDEX;
         }
@@ -884,7 +885,7 @@
 
     /**
      * @return subId of the DefaultSms subscription or
-     * the value INVALID_SUBSCRIPTION_ID if an error.
+     * a value < 0 if an error.
      *
      * @hide
      */
@@ -984,13 +985,13 @@
     //FIXME this is vulnerable to race conditions
     /** @hide */
     public boolean allDefaultsSelected() {
-        if (getDefaultDataSubId() == INVALID_SUBSCRIPTION_ID) {
+        if (!isValidSubscriptionId(getDefaultDataSubId())) {
             return false;
         }
-        if (getDefaultSmsSubId() == INVALID_SUBSCRIPTION_ID) {
+        if (!isValidSubscriptionId(getDefaultSmsSubId())) {
             return false;
         }
-        if (getDefaultVoiceSubId() == INVALID_SUBSCRIPTION_ID) {
+        if (!isValidSubscriptionId(getDefaultVoiceSubId())) {
             return false;
         }
         return true;
@@ -998,7 +999,7 @@
 
     /**
      * If a default is set to subscription which is not active, this will reset that default back to
-     * INVALID_SUBSCRIPTION_ID.
+     * an invalid subscription id, i.e. < 0.
      * @hide
      */
     public void clearDefaultsForInactiveSubIds() {
@@ -1017,13 +1018,13 @@
      * @return true if a valid subId else false
      * @hide
      */
-    public static boolean isValidSubId(int subId) {
+    public static boolean isValidSubscriptionId(int subId) {
         return subId > INVALID_SUBSCRIPTION_ID ;
     }
 
     /**
      * @return true if subId is an usable subId value else false. A
-     * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAUL_SUB_ID.
+     * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
      * @hide
      */
     public static boolean isUsableSubIdValue(int subId) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 83bf04f..d0ddeac 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -43,6 +43,7 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -3183,6 +3184,39 @@
     }
 
     /**
+     * Override the roaming preference for the current ICCID.
+     *
+     * Using this call, the carrier app (see #hasCarrierPrivileges) can override
+     * the platform's notion of a network operator being considered roaming or not.
+     * The change only affects the ICCID that was active when this call was made.
+     *
+     * If null is passed as any of the input, the corresponding value is deleted.
+     *
+     * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges.
+     *
+     * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs.
+     * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs.
+     * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs.
+     * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs.
+     * @return true if the operation was executed correctly.
+     *
+     * @hide
+     */
+    public boolean setRoamingOverride(List<String> gsmRoamingList,
+            List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
+            List<String> cdmaNonRoamingList) {
+        try {
+            return getITelephony().setRoamingOverride(gsmRoamingList, gsmNonRoamingList,
+                    cdmaRoamingList, cdmaNonRoamingList);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setRoamingOverride RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setRoamingOverride NPE", ex);
+        }
+        return false;
+    }
+
+    /**
      * Expose the rest of ITelephony to @SystemApi
      */
 
@@ -3509,8 +3543,15 @@
     /** @hide */
     @SystemApi
     public void setDataEnabled(boolean enable) {
+        setDataEnabled(SubscriptionManager.getDefaultDataSubId(), enable);
+    }
+
+    /** @hide */
+    @SystemApi
+    public void setDataEnabled(int subId, boolean enable) {
         try {
-            getITelephony().setDataEnabled(enable);
+            Log.d(TAG, "setDataEnabled: enabled=" + enable);
+            getITelephony().setDataEnabled(subId, enable);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#setDataEnabled", e);
         }
@@ -3519,12 +3560,21 @@
     /** @hide */
     @SystemApi
     public boolean getDataEnabled() {
+        return getDataEnabled(SubscriptionManager.getDefaultDataSubId());
+    }
+
+    /** @hide */
+    @SystemApi
+    public boolean getDataEnabled(int subId) {
+        boolean retVal;
         try {
-            return getITelephony().getDataEnabled();
+            retVal = getITelephony().getDataEnabled(subId);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#getDataEnabled", e);
+            retVal = false;
         }
-        return false;
+        Log.d(TAG, "getDataEnabled: retVal=" + retVal);
+        return retVal;
     }
 
     /**
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 9de938a..8740e19 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -269,6 +269,7 @@
     public String toString() {
         return "{ serviceType=" + mServiceType +
                 ", callType=" + mCallType +
+                ", restrictCause=" + mRestrictCause +
                 ", callExtras=" + mCallExtras.toString() +
                 ", mediaProfile=" + mMediaProfile.toString() + " }";
     }
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 2482249..0b1246b 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -228,6 +228,13 @@
      */
     public static final int CODE_ECBM_NOT_SUPPORTED = 901;
 
+    /**
+     * Network string error messages.
+     * mExtraMessage may have these values.
+     */
+    public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED
+            = "Forbidden. Not Authorized for Service";
+
     // For reason type
     public int mReasonType;
     // For main reason code
diff --git a/telephony/java/com/android/ims/internal/IImsConfig.aidl b/telephony/java/com/android/ims/internal/IImsConfig.aidl
index c5ccf5f..c17637c 100644
--- a/telephony/java/com/android/ims/internal/IImsConfig.aidl
+++ b/telephony/java/com/android/ims/internal/IImsConfig.aidl
@@ -49,22 +49,22 @@
  */
 interface IImsConfig {
     /**
-     * Gets the value for ims service/capabilities parameters from the master
+     * Gets the value for ims service/capabilities parameters from the provisioned
      * value storage. Synchronous blocking call.
      *
      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
      * @return value in Integer format.
      */
-    int getMasterValue(int item);
+    int getProvisionedValue(int item);
 
     /**
-     * Gets the value for ims service/capabilities parameters from the master
+     * Gets the value for ims service/capabilities parameters from the provisioned
      * value storage. Synchronous blocking call.
      *
      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
      * @return value in String format.
      */
-    String getMasterStringValue(int item);
+    String getProvisionedStringValue(int item);
 
     /**
      * Sets the value for IMS service/capabilities parameters by the operator device
@@ -112,4 +112,12 @@
      * @return void
      */
     oneway void setFeatureValue(int feature, int network, int value, ImsConfigListener listener);
+
+    /**
+     * Gets the value for IMS volte provisioned.
+     * This should be the same as the operator provisioned value if applies.
+     *
+     * @return void
+     */
+    boolean getVolteProvisioned();
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d19fa2c..ca14ca4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -679,14 +679,14 @@
      *
      * @param enable true to turn on, else false
      */
-    void setDataEnabled(boolean enable);
+    void setDataEnabled(int subId, boolean enable);
 
     /**
      * Get the user enabled state of Mobile Data.
      *
      * @return true on enabled
      */
-    boolean getDataEnabled();
+    boolean getDataEnabled(int subId);
 
     /**
      * Get P-CSCF address from PCO after data connection is established or modified.
@@ -792,6 +792,27 @@
     boolean setOperatorBrandOverride(String brand);
 
     /**
+     * Override the roaming indicator for the current ICCID.
+     *
+     * Using this call, the carrier app (see #hasCarrierPrivileges) can override
+     * the platform's notion of a network operator being considered roaming or not.
+     * The change only affects the ICCID that was active when this call was made.
+     *
+     * If null is passed as any of the input, the corresponding value is deleted.
+     *
+     * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges.
+     *
+     * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs.
+     * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs.
+     * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs.
+     * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs.
+     * @return true if the operation was executed correctly.
+     */
+    boolean setRoamingOverride(in List<String> gsmRoamingList,
+            in List<String> gsmNonRoamingList, in List<String> cdmaRoamingList,
+            in List<String> cdmaNonRoamingList);
+
+    /**
      * Returns the result and response from RIL for oem request
      *
      * @param oemReq the data is sent to ril.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index c67e5d7..92cd468 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -274,6 +274,15 @@
     public static final String ACTION_CARRIER_SETUP = "android.intent.action.ACTION_CARRIER_SETUP";
 
     /**
+     * <p>Broadcast Action: Indicates that the action is forbidden by network.
+     * <p class="note">
+     * This is for the OEM applications to understand about possible provisioning issues.
+     * Used in OMA-DM applications.
+     */
+    public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION
+            = "android.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
+
+    /**
      * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
      * of the form {@code *#*#<code>#*#*}. The intent will have the data URI:
      *
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
index 256a1d4..1216fc4 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RevealActivity.java
@@ -17,12 +17,14 @@
 package com.android.test.hwui;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorSet;
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewAnimationUtils;
@@ -37,6 +39,29 @@
     private boolean mShouldBlock;
     private int mIteration = 0;
 
+    private AnimatorListener mListener = new AnimatorListener() {
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            Log.d("Reveal", "onAnimatorStart " + animation);
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+            Log.d("Reveal", "onAnimationRepeat " + animation);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            Log.d("Reveal", "onAnimationEnd " + animation);
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            Log.d("Reveal", "onAnimationCancel " + animation);
+        }
+    };
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -59,6 +84,8 @@
         Animator animator = ViewAnimationUtils.createCircularReveal(view,
                 view.getWidth() / 2, view.getHeight() / 2,
                 0, Math.max(view.getWidth(), view.getHeight()));
+        Log.d("Reveal", "Calling start...");
+        animator.addListener(mListener);
         if (mIteration < 2) {
             animator.setDuration(DURATION);
             animator.start();
@@ -66,6 +93,7 @@
             AnimatorSet set = new AnimatorSet();
             set.playTogether(animator);
             set.setDuration(DURATION);
+            set.addListener(mListener);
             set.start();
         }
 
diff --git a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_left.xml b/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_left.xml
deleted file mode 100644
index b465ead..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_left.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="rotation"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="rotation"
-            android:valueFrom="0"
-            android:valueTo="-45"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_right.xml b/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_right.xml
deleted file mode 100644
index 49ac165..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_dot_right.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="rotation"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="rotation"
-            android:valueFrom="0"
-            android:valueTo="45"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_ic_signal_wifi_4_bar_48px_outlines_.xml b/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_ic_signal_wifi_4_bar_48px_outlines_.xml
deleted file mode 100644
index 1bdfde6..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_ic_signal_wifi_4_bar_48px_outlines_.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_mask.xml b/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_mask.xml
deleted file mode 100644
index 47efa18..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_mask.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 30.0523681641 -35.8077850342 30.0523681641 c 0.0 0.0 12.925994873 12.9778747559 12.925994873 12.9778747559 c 0.0 0.0 -2.61700439453 2.09387207031 -2.61700439453 2.09387207031 c 0.0 0.0 -13.1259613037 -12.9893035889 -13.1259613037 -12.9893035889 c 0.0 0.0 -34.6200408936 26.9699249268 -34.6200408936 26.9699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
-            android:valueTo="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 30.0523681641 -35.8077850342 30.0523681641 c 0.0 0.0 12.925994873 12.9778747559 12.925994873 12.9778747559 c 0.0 0.0 -2.61700439453 2.09387207031 -2.61700439453 2.09387207031 c 0.0 0.0 -13.1259613037 -12.9893035889 -13.1259613037 -12.9893035889 c 0.0 0.0 -34.6200408936 26.9699249268 -34.6200408936 26.9699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="pathData"
-            android:valueFrom="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 30.0523681641 -35.8077850342 30.0523681641 c 0.0 0.0 12.925994873 12.9778747559 12.925994873 12.9778747559 c 0.0 0.0 -2.61700439453 2.09387207031 -2.61700439453 2.09387207031 c 0.0 0.0 -13.1259613037 -12.9893035889 -13.1259613037 -12.9893035889 c 0.0 0.0 -34.6200408936 26.9699249268 -34.6200408936 26.9699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
-            android:valueTo="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 29.7398681641 -35.8077850342 29.7398681641 c 0.0 0.0 27.2634735107 27.4966583252 27.2634735107 27.4966583252 c 0.0 0.0 -2.61700439453 2.4063873291 -2.61700439453 2.4063873291 c 0.0 0.0 -27.4634399414 -27.508102417 -27.4634399414 -27.508102417 c 0.0 0.0 -34.6200408936 26.9699249268 -34.6200408936 26.9699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_path_1.xml b/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_path_1.xml
deleted file mode 100644
index 41fe866..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_bluethooth_v2_animation_path_1.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 10.6188659668 6.56344604492 c 0.0 0.0 21.7386016846 23.1297454834 21.7386016846 23.1297454834 "
-            android:valueTo="M 10.6188659668 6.56344604492 c 0.0 0.0 21.7386016846 23.1297454834 21.7386016846 23.1297454834 "
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_bluethooth_v2_path_1_pathdata_interpolator" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="pathData"
-            android:valueFrom="M 10.6188659668 6.56344604492 c 0.0 0.0 21.7386016846 23.1297454834 21.7386016846 23.1297454834 "
-            android:valueTo="M 8.62858581543 4.33430480957 c 0.0 0.0 28.1998138428 30.2359008789 28.1998138428 30.2359008789 "
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_bluethooth_v2_path_1_pathdata_interpolator" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_frame.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_frame.xml
deleted file mode 100644
index 9cea85d..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_frame.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_screen.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_screen.xml
deleted file mode 100644
index 61b018b..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_screen.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="alpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="alpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave1.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave1.xml
deleted file mode 100644
index 002f7b2..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave1.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -4.0 a 4 4 0 0 1 4 4 a 4 4 0 0 1 -4 4 a 4 4 0 0 1 -4 -4 a 4 4 0 0 1 4 -4 Z"
-            android:valueTo="M 0 -4.0 a 4 4 0 0 1 4 4 a 4 4 0 0 1 -4 4 a 4 4 0 0 1 -4 -4 a 4 4 0 0 1 4 -4 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -4.0 a 4 4 0 0 1 4 4 a 4 4 0 0 1 -4 4 a 4 4 0 0 1 -4 -4 a 4 4 0 0 1 4 -4 Z"
-            android:valueTo="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave2.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave2.xml
deleted file mode 100644
index 0c2ee21..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave2.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -12.0 a 12 12 0 0 1 12 12 a 12 12 0 0 1 -12 12 a 12 12 0 0 1 -12 -12 a 12 12 0 0 1 12 -12 Z"
-            android:valueTo="M 0 -12.0 a 12 12 0 0 1 12 12 a 12 12 0 0 1 -12 12 a 12 12 0 0 1 -12 -12 a 12 12 0 0 1 12 -12 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -12.0 a 12 12 0 0 1 12 12 a 12 12 0 0 1 -12 12 a 12 12 0 0 1 -12 -12 a 12 12 0 0 1 12 -12 Z"
-            android:valueTo="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave3.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave3.xml
deleted file mode 100644
index a75b2eaf..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave3.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueTo="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="167"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueTo="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave5.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave5.xml
deleted file mode 100644
index 7e79b94..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave5.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueTo="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueTo="M 0 -12.0 a 12 12 0 0 1 12 12 a 12 12 0 0 1 -12 12 a 12 12 0 0 1 -12 -12 a 12 12 0 0 1 12 -12 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave6.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave6.xml
deleted file mode 100644
index 0917e0e..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_wave6.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueTo="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="pathData"
-            android:valueFrom="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-            android:valueTo="M 0 -4.0 a 4 4 0 0 1 4 4 a 4 4 0 0 1 -4 4 a 4 4 0 0 1 -4 -4 a 4 4 0 0 1 4 -4 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_waves.xml b/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_waves.xml
deleted file mode 100644
index 9cea85d..0000000
--- a/tests/VectorDrawableTest/res/anim/ic_cast_v2_animation_waves.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2.xml b/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2.xml
deleted file mode 100644
index 5f068fc..0000000
--- a/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<!-- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:name="root_bt">
-    <group
-        android:name="ic_signal_wifi_4_bar_48px_outlines_"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_wifi_4_bar_48px_outlines__pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 30.0523681641 -35.8077850342 30.0523681641 c 0.0 0.0 12.925994873 12.9778747559 12.925994873 12.9778747559 c 0.0 0.0 -2.61700439453 2.09387207031 -2.61700439453 2.09387207031 c 0.0 0.0 -13.1259613037 -12.9893035889 -13.1259613037 -12.9893035889 c 0.0 0.0 -34.6200408936 26.9699249268 -34.6200408936 26.9699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z" />
-            <group
-                android:name="cross"
-                android:rotation="-1.88453332239" >
-                <path
-                    android:name="path_1"
-                    android:pathData="M 10.6188659668 6.56344604492 c 0.0 0.0 21.7386016846 23.1297454834 21.7386016846 23.1297454834 "
-                    android:strokeColor="#FF777777"
-                    android:strokeWidth="4"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="bluetooth"
-                android:translateX="23.38789"
-                android:translateY="18.72031" >
-                <path
-                    android:name="path_4"
-                    android:pathData="M 11.3999938965 -8.60000610352 c 0.0 0.0 -11.3999938965 -11.3999938965 -11.3999938965 -11.3999938965 c 0 0 -2 0 -2 0 c 0 0 0 15.1999969482 0 15.1999969482 c 0 0.0 -9.19999694824 -9.19999694824 -9.19999694824 -9.19999694824 c 0.0 0 -2.80000305176 2.80000305176 -2.80000305176 2.80000305176 c 0 0.0 11.1999969482 11.1999969482 11.1999969482 11.1999969482 c 0.0 0 -11.1999969482 11.1999969482 -11.1999969482 11.1999969482 c 0 0.0 2.80000305176 2.80000305176 2.80000305176 2.80000305176 c 0.0 0 9.19999694824 -9.19999694824 9.19999694824 -9.19999694824 c 0 0.0 0 15.1999969482 0 15.1999969482 c 0 0 2 0 2 0 c 0 0 11.3999938965 -11.3999938965 11.3999938965 -11.3999938965 c 0.0 0.0 -8.59999084473 -8.60000610352 -8.59999084473 -8.60000610352 c 0.0 0 8.59999084473 -8.60000610352 8.59999084473 -8.60000610352 Z M 2 -12.3000030518 c 0 0.0 3.80000305176 3.80000305176 3.80000305176 3.80000305176 c 0.0 0.0 -3.80000305176 3.69999694824 -3.80000305176 3.69999694824 c 0 0.0 0 -7.5 0 -7.5 Z M 5.80000305176 8.60000610352 c 0.0 0.0 -3.80000305176 3.69999694824 -3.80000305176 3.69999694824 c 0 0.0 0 -7.5 0 -7.5 c 0 0.0 3.80000305176 3.80000305176 3.80000305176 3.80000305176 Z"
-                    android:fillColor="#FF777777" />
-            </group>
-            <group
-                android:name="dot_left"
-                android:translateX="20.16992"
-                android:translateY="18.64258" >
-                <group
-                    android:name="dot_left_pivot"
-                    android:translateX="-20.16992"
-                    android:translateY="-18.64258" >
-                    <path
-                        android:name="dot_left_1"
-                        android:pathData="M 13.3878936768 18.7203063965 c 0.0 0.0 -4.0 -4.0 -4.0 -4.0 c 0.0 0.0 -4.0 4.0 -4.0 4.0 c 0.0 0.0 4.0 4.0 4.0 4.0 c 0.0 0.0 4.0 -4.0 4.0 -4.0 Z"
-                        android:fillColor="#FF777777" />
-                </group>
-            </group>
-            <group
-                android:name="dot_right"
-                android:translateX="26.16094"
-                android:translateY="18.60898" >
-                <group
-                    android:name="dot_right_pivot"
-                    android:translateX="-26.16094"
-                    android:translateY="-18.60898" >
-                    <path
-                        android:name="dot_right_1"
-                        android:pathData="M 37.3878936768 14.7203063965 c 0.0 0.0 -4.0 4.0 -4.0 4.0 c 0.0 0.0 4.0 4.0 4.0 4.0 c 0.0 0.0 4.0 -4.0 4.0 -4.0 c 0.0 0.0 -4.0 -4.0 -4.0 -4.0 Z"
-                        android:fillColor="#FF777777" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2_animation.xml b/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2_animation.xml
deleted file mode 100644
index aa05468..0000000
--- a/tests/VectorDrawableTest/res/drawable/ic_bluethooth_v2_animation.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!-- 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_bluethooth_v2" >
-    <target
-        android:name="root_bt"
-        android:animation="@anim/ic_bluethooth_v2_animation_ic_signal_wifi_4_bar_48px_outlines_" />
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_bluethooth_v2_animation_mask" />
-    <target
-        android:name="path_1"
-        android:animation="@anim/ic_bluethooth_v2_animation_path_1" />
-    <target
-        android:name="dot_left"
-        android:animation="@anim/ic_bluethooth_v2_animation_dot_left" />
-    <target
-        android:name="dot_right"
-        android:animation="@anim/ic_bluethooth_v2_animation_dot_right" />
-</animated-vector>
diff --git a/tests/VectorDrawableTest/res/drawable/ic_cast_v2.xml b/tests/VectorDrawableTest/res/drawable/ic_cast_v2.xml
deleted file mode 100644
index 207804a..0000000
--- a/tests/VectorDrawableTest/res/drawable/ic_cast_v2.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<!-- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_cast_connected_48px_outlines"
-        android:translateX="24"
-        android:translateY="24" >
-        <group
-            android:name="ic_cast_connected_48px_outlines_pivot"
-            android:translateX="-24"
-            android:translateY="-24" >
-            <clip-path
-                android:name="mask_1"
-                android:pathData="M 46.6999969482 3.80000305176 c 0.0 0.0 -44.6999664307 0.0 -44.6999664307 0.0 c 0.0 0.0 0.29997253418 38.25 0.29997253418 38.25 c 0.0 0.0 44.8000030518 -0.100021362305 44.8000030518 -0.100021362305 c 0.0 0.0 -0.400009155273 -38.1499786377 -0.400009155273 -38.1499786377 Z" />
-            <group
-                android:name="waves"
-                android:alpha="0.5" >
-                <group
-                    android:name="wave1_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="wave1"
-                        android:pathData="M 0 -4.0 a 4 4 0 0 1 4 4 a 4 4 0 0 1 -4 4 a 4 4 0 0 1 -4 -4 a 4 4 0 0 1 4 -4 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-                <group
-                    android:name="wave2_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="wave2"
-                        android:pathData="M 0 -12.0 a 12 12 0 0 1 12 12 a 12 12 0 0 1 -12 12 a 12 12 0 0 1 -12 -12 a 12 12 0 0 1 12 -12 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-                <group
-                    android:name="wave3_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="wave3"
-                        android:pathData="M 0 -20.0 a 20 20 0 0 1 20 20 a 20 20 0 0 1 -20 20 a 20 20 0 0 1 -20 -20 a 20 20 0 0 1 20 -20 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-                <group
-                    android:name="wave5_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="wave5"
-                        android:pathData="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-                <group
-                    android:name="wave6_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="wave6"
-                        android:pathData="M 0 -0.0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 a 0 0 0 0 1 0 0 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-                <group
-                    android:name="ellipse_path_1_position"
-                    android:translateX="2"
-                    android:translateY="42" >
-                    <path
-                        android:name="ellipse_path_1"
-                        android:pathData="M 0 -2.0 a 2 2 0 0 1 2 2 a 2 2 0 0 1 -2 2 a 2 2 0 0 1 -2 -2 a 2 2 0 0 1 2 -2 Z"
-                        android:strokeColor="#FF777777"
-                        android:strokeWidth="4"
-                        android:fillColor="#00000000" />
-                </group>
-            </group>
-            <group
-                android:name="screen"
-                android:translateX="24"
-                android:translateY="24"
-                android:alpha="0" >
-                <path
-                    android:name="screen_1"
-                    android:pathData="M 14 -10 c 0 0 -28 0 -28 0 c 0 0 0 3.30000305176 0 3.30000305176 c 7.89999389648 2.59999084473 14.1999969482 8.80000305176 16.6999969482 16.6999969482 c 0.0 0 11.3000030518 0 11.3000030518 0 c 0 0 0 -20 0 -20 Z"
-                    android:fillColor="#FF777777" />
-            </group>
-            <group
-                android:name="frame"
-                android:translateX="24"
-                android:translateY="24"
-                android:alpha="0.5" >
-                <path
-                    android:name="box"
-                    android:pathData="M 18 -18 c 0 0 -36 0 -36 0 c -2.19999694824 0 -4 1.80000305176 -4 4 c 0 0 0 6 0 6 c 0 0 4 0 4 0 c 0 0 0 -6 0 -6 c 0 0 36 0 36 0 c 0 0 0 28 0 28 c 0 0 -14 0 -14 0 c 0 0 0 4 0 4 c 0 0 14 0 14 0 c 2.19999694824 0 4 -1.80000305176 4 -4 c 0 0 0 -28 0 -28 c 0 -2.19999694824 -1.80000305176 -4 -4 -4 Z"
-                    android:fillColor="#FF777777" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/tests/VectorDrawableTest/res/drawable/ic_cast_v2_animation.xml b/tests/VectorDrawableTest/res/drawable/ic_cast_v2_animation.xml
deleted file mode 100644
index 7884212..0000000
--- a/tests/VectorDrawableTest/res/drawable/ic_cast_v2_animation.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_cast_v2" >
-    <target
-        android:name="waves"
-        android:animation="@anim/ic_cast_v2_animation_waves" />
-    <target
-        android:name="wave1"
-        android:animation="@anim/ic_cast_v2_animation_wave1" />
-    <target
-        android:name="wave2"
-        android:animation="@anim/ic_cast_v2_animation_wave2" />
-    <target
-        android:name="wave3"
-        android:animation="@anim/ic_cast_v2_animation_wave3" />
-    <target
-        android:name="wave5"
-        android:animation="@anim/ic_cast_v2_animation_wave5" />
-    <target
-        android:name="wave6"
-        android:animation="@anim/ic_cast_v2_animation_wave6" />
-    <target
-        android:name="screen"
-        android:animation="@anim/ic_cast_v2_animation_screen" />
-    <target
-        android:name="frame"
-        android:animation="@anim/ic_cast_v2_animation_frame" />
-</animated-vector>
diff --git a/tests/VectorDrawableTest/res/interpolator/ic_bluethooth_v2_path_1_pathdata_interpolator.xml b/tests/VectorDrawableTest/res/interpolator/ic_bluethooth_v2_path_1_pathdata_interpolator.xml
deleted file mode 100644
index 4917f77..0000000
--- a/tests/VectorDrawableTest/res/interpolator/ic_bluethooth_v2_path_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- 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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0 0 c 0.16666666667 0.0 0.2 1.0 1.0 1.0" />
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
index c4dfb84..ecc7782 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
@@ -29,8 +29,6 @@
             R.drawable.ic_rotate_2_portrait_v2_animation,
             R.drawable.ic_signal_airplane_v2_animation,
             R.drawable.ic_hourglass_animation,
-            R.drawable.ic_cast_v2_animation,
-            R.drawable.ic_bluethooth_v2_animation,
             R.drawable.animation_vector_linear_progress_bar,
             R.drawable.animation_vector_drawable_grouping_1,
             R.drawable.animation_vector_progress_bar,
diff --git a/tests/utils/Android.mk b/tests/utils/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/tests/utils/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/tests/utils/DummyIME/Android.mk b/tests/utils/DummyIME/Android.mk
new file mode 100644
index 0000000..c8d9f87
--- /dev/null
+++ b/tests/utils/DummyIME/Android.mk
@@ -0,0 +1,26 @@
+#
+# 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_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := DummyIME
+
+include $(BUILD_PACKAGE)
diff --git a/tests/utils/DummyIME/AndroidManifest.xml b/tests/utils/DummyIME/AndroidManifest.xml
new file mode 100644
index 0000000..fd17a52
--- /dev/null
+++ b/tests/utils/DummyIME/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<!--
+/*
+ * Copyright 2006, 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.
+ */
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.testing.dummyime">
+    <application android:label="Dummy IME">
+        <service android:name="DummyIme"
+                android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/method" />
+        </service>
+        <activity android:name=".ImePreferences" android:label="Dummy IME Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/utils/DummyIME/res/xml/method.xml b/tests/utils/DummyIME/res/xml/method.xml
new file mode 100644
index 0000000..43a330e
--- /dev/null
+++ b/tests/utils/DummyIME/res/xml/method.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Search Manager. -->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+        android:settingsActivity="com.android.testing.dummyime.ImePreferences">
+    <subtype
+        android:label="Generic"
+        android:imeSubtypeLocale="en_US"
+        android:imeSubtypeMode="keyboard" />
+</input-method>
\ No newline at end of file
diff --git a/tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java b/tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java
new file mode 100644
index 0000000..7b7a39a
--- /dev/null
+++ b/tests/utils/DummyIME/src/com/android/testing/dummyime/DummyIme.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.testing.dummyime;
+
+import android.inputmethodservice.InputMethodService;
+
+/**
+ * Dummy IME implementation that basically does nothing
+ */
+public class DummyIme extends InputMethodService {
+
+    @Override
+    public boolean onEvaluateFullscreenMode() {
+        return false;
+    }
+
+    @Override
+    public boolean onEvaluateInputViewShown() {
+        return false;
+    }
+}
diff --git a/cmds/app_process/sigchain_proxy.cpp b/tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
similarity index 69%
copy from cmds/app_process/sigchain_proxy.cpp
copy to tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
index bb7a678..41036ab 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/tests/utils/DummyIME/src/com/android/testing/dummyime/ImePreferences.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,4 +14,13 @@
  * limitations under the License.
  */
 
-#include "sigchainlib/sigchain.cc"
+package com.android.testing.dummyime;
+
+import android.preference.PreferenceActivity;
+
+/**
+ * Dummy IME preference activity
+ */
+public class ImePreferences extends PreferenceActivity {
+
+}
diff --git a/tests/utils/SleepUtils/AlarmService/Android.mk b/tests/utils/SleepUtils/AlarmService/Android.mk
new file mode 100644
index 0000000..9022f03
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/Android.mk
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += \
+    src/com/android/testing/alarmservice/Alarm.aidl
+LOCAL_PACKAGE_NAME := SleepUtilsAlarmService
+LOCAL_SDK_VERSION := 7
+include $(BUILD_PACKAGE)
diff --git a/tests/utils/SleepUtils/AlarmService/AndroidManifest.xml b/tests/utils/SleepUtils/AlarmService/AndroidManifest.xml
new file mode 100644
index 0000000..1b6de39
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?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. -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.testing.alarmservice" >
+
+    <uses-sdk android:minSdkVersion="7" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <application android:label="Sleep Utils Alarm Service">
+        <service android:name=".AlarmService"
+            android:label="Sleep Utils Alarm Service"
+            android:exported="true"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="com.android.testing.ALARM_SERVICE" />
+            </intent-filter>
+        </service>
+        <receiver android:name=".WakeUpCall">
+            <intent-filter>
+                <action android:name="com.android.testing.alarmservice.WAKEUP" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/cmds/app_process/sigchain_proxy.cpp b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/Alarm.aidl
similarity index 73%
rename from cmds/app_process/sigchain_proxy.cpp
rename to tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/Alarm.aidl
index bb7a678..62a8c48 100644
--- a/cmds/app_process/sigchain_proxy.cpp
+++ b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/Alarm.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,4 +14,10 @@
  * limitations under the License.
  */
 
-#include "sigchainlib/sigchain.cc"
+package com.android.testing.alarmservice;
+
+interface Alarm {
+    int prepare();
+    int setAlarmAndWait(long timeoutMills);
+    int done();
+}
\ No newline at end of file
diff --git a/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmImpl.java b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmImpl.java
new file mode 100644
index 0000000..122d55d
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmImpl.java
@@ -0,0 +1,77 @@
+/*
+ * 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.testing.alarmservice;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.testing.alarmservice.Alarm.Stub;
+
+public class AlarmImpl extends Stub {
+
+    private static final String LOG_TAG = AlarmImpl.class.getSimpleName();
+
+    private Context mContext;
+
+    public AlarmImpl(Context context) {
+        super();
+        mContext = context;
+    }
+
+    @Override
+    public int prepare() throws RemoteException {
+        WakeUpController.getController().getWakeLock().acquire();
+        Log.d(LOG_TAG, "AlarmService prepared, wake lock acquired");
+        return 0;
+    }
+
+    @Override
+    public int setAlarmAndWait(long timeoutMills) throws RemoteException {
+        // calculate when device should be waken up
+        long atTime = SystemClock.elapsedRealtime() + timeoutMills;
+        AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        Intent wakupIntent = new Intent(WakeUpCall.WAKEUP_CALL);
+        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, wakupIntent, 0);
+        // set alarm, which will be delivered in form of the wakeupIntent
+        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, atTime, pi);
+        Log.d(LOG_TAG, String.format("Alarm set: %d, giving up wake lock", atTime));
+        Object lock = WakeUpController.getController().getWakeSync();
+        // release wakelock and wait for the lock to be poked from the broadcast receiver
+        WakeUpController.getController().getWakeLock().release();
+        // does not really matter if device enters suspend before we start waiting on lock
+        synchronized (lock) {
+            try {
+                lock.wait();
+            } catch (InterruptedException e) {
+            }
+        }
+        Log.d(LOG_TAG, String.format("Alarm triggered, done waiting"));
+        return 0;
+    }
+
+    @Override
+    public int done() throws RemoteException {
+        WakeUpController.getController().getWakeLock().release();
+        return 0;
+    }
+
+}
diff --git a/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmService.java b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmService.java
new file mode 100644
index 0000000..576a1cf
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/AlarmService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.testing.alarmservice;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class AlarmService extends Service {
+
+    private AlarmImpl mAlarmImpl = null;
+    static Context sContext;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        sContext = this;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return getAlarmImpl();
+    }
+
+    private AlarmImpl getAlarmImpl() {
+        if (mAlarmImpl == null) {
+            mAlarmImpl = new AlarmImpl(this);
+        }
+        return mAlarmImpl;
+    }
+
+    @Override
+    public void onDestroy() {
+        sContext = null;
+        super.onDestroy();
+    }
+}
diff --git a/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpCall.java b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpCall.java
new file mode 100644
index 0000000..f4bb4db
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpCall.java
@@ -0,0 +1,42 @@
+/*
+ * 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.testing.alarmservice;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * The receiver for the alarm we set
+ *
+ */
+public class WakeUpCall extends BroadcastReceiver {
+
+    public static final String WAKEUP_CALL = "com.android.testing.alarmservice.WAKEUP";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // we acquire wakelock without release because user is supposed to manually release it
+        WakeUpController.getController().getWakeLock().acquire();
+        Object lock = WakeUpController.getController().getWakeSync();
+        synchronized (lock) {
+            // poke the lock so the service side can be woken from waiting on the lock
+            lock.notifyAll();
+        }
+    }
+
+}
diff --git a/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpController.java b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpController.java
new file mode 100644
index 0000000..478371f
--- /dev/null
+++ b/tests/utils/SleepUtils/AlarmService/src/com/android/testing/alarmservice/WakeUpController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.testing.alarmservice;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
+
+/**
+ * A singleton used for controlling and sharing of states/wakelocks
+ *
+ */
+public class WakeUpController {
+
+    private static final String LOG_TAG = WakeUpController.class.getName();
+    private static WakeUpController mController = null;
+    private WakeLock mWakeLock = null;
+    private Object mWakeSync = new Object();
+
+    private WakeUpController() {
+        Log.i(LOG_TAG, "Created instance: 0x" + Integer.toHexString(this.hashCode()));
+    }
+
+    public static synchronized WakeUpController getController() {
+        if (mController == null) {
+            mController = new WakeUpController();
+        }
+        return mController;
+    }
+
+    public WakeLock getWakeLock() {
+        if (mWakeLock == null) {
+            PowerManager pm =
+                    (PowerManager) AlarmService.sContext.getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "testing-alarmservice");
+            Log.i(LOG_TAG, "Create wakelock: 0x" + Integer.toHexString(mWakeLock.hashCode()));
+        }
+        return mWakeLock;
+    }
+
+    public Object getWakeSync() {
+        return mWakeSync;
+    }
+}
diff --git a/tests/utils/SleepUtils/Android.mk b/tests/utils/SleepUtils/Android.mk
new file mode 100644
index 0000000..0e65e22
--- /dev/null
+++ b/tests/utils/SleepUtils/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/tests/utils/SleepUtils/README b/tests/utils/SleepUtils/README
new file mode 100644
index 0000000..bfe07da
--- /dev/null
+++ b/tests/utils/SleepUtils/README
@@ -0,0 +1,23 @@
+This folder contains utils to properly perform timed suspend and wakeup.
+
+AlarmService - a service that client can bind to and perform:
+1) holding wakelock (singleton to this service)
+2) setting alarm for a specified period and releasing the wakelock; service
+   call will block until alarm has been triggered and the wakelock is held
+3) releasing the wakelock
+
+SleepHelper - a self instrumentation meant as a convenient way to trigger
+the service functions from command line. Corresponding to service function
+above, supported operations are:
+1) holding wakelock
+am instrument -w -e command prepare \
+  com.android.testing.sleephelper/.SetAlarm
+
+2) setting alarm and wait til triggered
+am instrument -w -e command set_wait \
+  -e param <time in ms> com.android.testing.sleephelper/.SetAlarm
+Note: for the function to work properly, "-w" parameter is required
+
+3) releasing wakelock
+am instrument -w -e command done \
+  com.android.testing.sleephelper/.SetAlarm
diff --git a/tests/utils/SleepUtils/SleepHelper/Android.mk b/tests/utils/SleepUtils/SleepHelper/Android.mk
new file mode 100644
index 0000000..f8267fd
--- /dev/null
+++ b/tests/utils/SleepUtils/SleepHelper/Android.mk
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += \
+    ../AlarmService/src/com/android/testing/alarmservice/Alarm.aidl
+LOCAL_SDK_VERSION := 7
+LOCAL_PACKAGE_NAME := SleepUtilsSleepHelper
+
+include $(BUILD_PACKAGE)
diff --git a/tests/utils/SleepUtils/SleepHelper/AndroidManifest.xml b/tests/utils/SleepUtils/SleepHelper/AndroidManifest.xml
new file mode 100644
index 0000000..0f1d491
--- /dev/null
+++ b/tests/utils/SleepUtils/SleepHelper/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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. -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.testing.sleephelper">
+
+    <uses-sdk android:minSdkVersion="7" />
+    <instrumentation android:label="Sleep Helper"
+                     android:name="com.android.testing.sleephelper.SetAlarm"
+                     android:targetPackage="com.android.testing.sleephelper" />
+
+    <application android:label="Sleep Utils Sleep Helper">
+        <uses-library android:name="android.test.runner" />
+    </application>
+</manifest>
diff --git a/tests/utils/SleepUtils/SleepHelper/src/com/android/testing/sleephelper/SetAlarm.java b/tests/utils/SleepUtils/SleepHelper/src/com/android/testing/sleephelper/SetAlarm.java
new file mode 100644
index 0000000..b558741
--- /dev/null
+++ b/tests/utils/SleepUtils/SleepHelper/src/com/android/testing/sleephelper/SetAlarm.java
@@ -0,0 +1,152 @@
+/*
+ * 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.testing.sleephelper;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.testing.alarmservice.Alarm;
+
+public class SetAlarm extends Instrumentation {
+
+    private static final String COMMAND = "command";
+    private static final String PARAM = "param";
+    private static final String CMD_PREPARE = "prepare";
+    private static final String CMD_SET = "set_wait";
+    private static final String CMD_DONE = "done";
+    private static final String SERVICE_ACTION = "com.android.testing.ALARM_SERVICE";
+    private static final String SERVICE_PKG = "com.android.testing.alarmservice";
+    private static final String LOG_TAG = SetAlarm.class.getSimpleName();
+
+    private Alarm mAlarmService = null;
+    private Bundle mArgs = null;
+    private String mCommand = null;
+    private Intent mServceIntent = new Intent(SERVICE_ACTION).setPackage(SERVICE_PKG);
+
+    private ServiceConnection mConn = new ServiceConnection() {
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(LOG_TAG, "Service disconnected.");
+            mAlarmService = null;
+            errorFinish("service disconnected");
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(LOG_TAG, "Service connected.");
+            mAlarmService = Alarm.Stub.asInterface(service);
+            handleCommands();
+        }
+    };
+
+
+    private void handleCommands() {
+        if (CMD_PREPARE.equals(mCommand)) {
+            callPrepare();
+        } else if (CMD_SET.equals(mCommand)) {
+            String paramString = mArgs.getString(PARAM);
+            if (paramString == null) {
+                errorFinish("argument expected for alarm time");
+            }
+            long timeout = -1;
+            try {
+                timeout = Long.parseLong(paramString);
+            } catch (NumberFormatException nfe) {
+                errorFinish("a number argument is expected");
+            }
+            callSetAndWait(timeout);
+        } else if (CMD_DONE.equals(mCommand)) {
+            callDone();
+        } else {
+            errorFinish("Unrecognized command: " + mCommand);
+        }
+        finish(Activity.RESULT_OK, new Bundle());
+    }
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+        mCommand = arguments.getString(COMMAND);
+        if ("true".equals(arguments.getString("debug"))) {
+            Debug.waitForDebugger();
+        }
+        if (mCommand == null) {
+            errorFinish("No command specified");
+        }
+        mArgs = arguments;
+        connectToAlarmService();
+    }
+
+    private void errorFinish(String msg) {
+        Bundle ret = new Bundle();
+        ret.putString("error", msg);
+        finish(Activity.RESULT_CANCELED, ret);
+    }
+
+    private void connectToAlarmService() {
+        // start the service with an intent, this ensures the service keeps running after unbind
+        ComponentName cn = getContext().startService(mServceIntent);
+        if (cn == null) {
+            errorFinish("failed to start service");
+        }
+        if (!getContext().bindService(mServceIntent, mConn, Context.BIND_AUTO_CREATE)) {
+            errorFinish("failed to bind service");
+        }
+    }
+
+    private void callPrepare() {
+        try {
+            mAlarmService.prepare();
+        } catch (RemoteException e) {
+            errorFinish("RemoteExeption in prepare()");
+        } finally {
+            getContext().unbindService(mConn);
+        }
+    }
+
+    private void callDone() {
+        try {
+            mAlarmService.done();
+        } catch (RemoteException e) {
+            errorFinish("RemoteExeption in prepare()");
+        } finally {
+            getContext().unbindService(mConn);
+        }
+        // explicitly stop the service (started in prepare()) so that the service is now free
+        // to be reclaimed
+        getContext().stopService(mServceIntent);
+    }
+
+    private void callSetAndWait(long timeoutMills) {
+        try {
+            mAlarmService.setAlarmAndWait(timeoutMills);
+        } catch (RemoteException e) {
+            errorFinish("RemoteExeption in setAlarmAndWait()");
+        } finally {
+            getContext().unbindService(mConn);
+        }
+    }
+}
diff --git a/tests/utils/SleepUtils/WakeLoopService/Android.mk b/tests/utils/SleepUtils/WakeLoopService/Android.mk
new file mode 100644
index 0000000..a8a944b
--- /dev/null
+++ b/tests/utils/SleepUtils/WakeLoopService/Android.mk
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := WakeupLoopService
+LOCAL_SDK_VERSION := 7
+include $(BUILD_PACKAGE)
diff --git a/tests/utils/SleepUtils/WakeLoopService/AndroidManifest.xml b/tests/utils/SleepUtils/WakeLoopService/AndroidManifest.xml
new file mode 100644
index 0000000..a7028c4
--- /dev/null
+++ b/tests/utils/SleepUtils/WakeLoopService/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?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. -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.test.wakeuploop" >
+
+    <uses-sdk android:minSdkVersion="7" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application android:label="Auto Wakeup Loop">
+        <service android:name=".WakeLoopService"
+            android:label="Wakup Loop Service"
+            android:exported="true"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.test.wakeuploop.WAKEUP_SERVICE" />
+            </intent-filter>
+        </service>
+        <receiver android:name=".WakeUpCall">
+            <intent-filter>
+                <action android:name="android.test.wakeuploop.WAKEUP" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/FileUtil.java b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/FileUtil.java
new file mode 100644
index 0000000..c8b075b
--- /dev/null
+++ b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/FileUtil.java
@@ -0,0 +1,53 @@
+/*
+ * 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.test.wakeuploop;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+    private static FileUtil sInst = null;
+    private static DateFormat sDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+
+    private FileUtil() {};
+
+    public static FileUtil get() {
+        if (sInst == null) {
+            sInst = new FileUtil();
+        }
+        return sInst;
+    }
+
+    public void writeDateToFile(File file) {
+        try {
+            FileOutputStream fos = new FileOutputStream(file);
+            fos.write(sDateFormat.format(new Date()).getBytes());
+            fos.write('\n');
+            fos.flush();
+            fos.close();
+        } catch (IOException ioe) {
+            Log.e("FileUtil", "exception writing date to file", ioe);
+        }
+    }
+}
diff --git a/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeLoopService.java b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeLoopService.java
new file mode 100644
index 0000000..4f557b8
--- /dev/null
+++ b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeLoopService.java
@@ -0,0 +1,98 @@
+/*
+ * 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.test.wakeuploop;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.File;
+
+public class WakeLoopService extends Service {
+
+    private static final String LOG_TAG = WakeLoopService.class.getSimpleName();
+    static final String WAKEUP_INTERNAL = "WAKEUP_INTERVAL";
+    static final String MAX_LOOP = "MAX_LOOP";
+    static final String STOP_CALLBACK = "STOP_CALLBACK";
+    static final String THIS_LOOP = "THIS_LOOP";
+    static final int MSG_STOP_SERVICE = 0xd1ed1e;
+
+    private final Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_STOP_SERVICE) {
+                stopSelf();
+            } else {
+                super.handleMessage(msg);
+            }
+        };
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        // no binding, just start via intent
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        // get wakeup interval from intent
+        long wakeupInterval = intent.getLongExtra(WAKEUP_INTERNAL, 0);
+        long maxLoop = intent.getLongExtra(MAX_LOOP, 0);
+
+        if (wakeupInterval == 0) {
+            // stop and error
+            Log.e(LOG_TAG, "No wakeup interval specified, not starting the service");
+            stopSelf();
+            return START_NOT_STICKY;
+        }
+        FileUtil.get().writeDateToFile(new File(Environment.getExternalStorageDirectory(),
+                "wakeup-loop-start.txt"));
+        Log.d(LOG_TAG, String.format("WakeLoop: STARTED interval = %d, total loop = %d",
+                wakeupInterval, maxLoop));
+        // calculate when device should be waken up
+        long atTime = SystemClock.elapsedRealtime() + wakeupInterval;
+        AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+        Intent wakupIntent = new Intent(WakeUpCall.WAKEUP_CALL)
+            .putExtra(WAKEUP_INTERNAL, wakeupInterval)
+            .putExtra(MAX_LOOP, maxLoop)
+            .putExtra(THIS_LOOP, 0L)
+            .putExtra(STOP_CALLBACK, new Messenger(mHandler));
+        PendingIntent pi = PendingIntent.getBroadcast(this, 0, wakupIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        // set alarm, which will be delivered in form of the wakeupIntent
+        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, atTime, pi);
+        return START_NOT_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.d(LOG_TAG, "WakeLoop: STOPPED");
+        // cancel alarms first
+        Intent intent = new Intent(WakeUpCall.WAKEUP_CALL)
+            .putExtra(WakeUpCall.CANCEL, "true");
+        sendBroadcast(intent);
+    }
+}
diff --git a/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeUpCall.java b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeUpCall.java
new file mode 100644
index 0000000..8347bbf0
--- /dev/null
+++ b/tests/utils/SleepUtils/WakeLoopService/src/android/test/wakeuploop/WakeUpCall.java
@@ -0,0 +1,112 @@
+/*
+ * 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.test.wakeuploop;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Environment;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * The receiver for the alarm we set
+ *
+ */
+public class WakeUpCall extends BroadcastReceiver {
+    private static final String LOG_TAG = WakeUpCall.class.getSimpleName();
+    static final String WAKEUP_CALL = "android.test.wakeuploop.WAKEUP";
+    static final String CANCEL = "CANCEL";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        boolean cancel = intent.hasExtra(CANCEL);
+        if (!cancel) {
+            long maxLoop = intent.getLongExtra(WakeLoopService.MAX_LOOP, 0);
+            long wakeupInterval = intent.getLongExtra(WakeLoopService.WAKEUP_INTERNAL, 0);
+            long thisLoop = intent.getLongExtra(WakeLoopService.THIS_LOOP, -1);
+            Log.d(LOG_TAG, String.format("incoming: interval = %d, max loop = %d, this loop = %d",
+                    wakeupInterval, maxLoop, thisLoop));
+            if (thisLoop == -1) {
+                Log.e(LOG_TAG, "no valid loop count received, trying to stop service");
+                stopService(intent);
+                return;
+            }
+            if (wakeupInterval == 0) {
+                Log.e(LOG_TAG, "no valid wakeup interval received, trying to stop service");
+                stopService(intent);
+                return;
+            }
+            thisLoop++;
+            Log.d(LOG_TAG, String.format("WakeLoop - iteration %d of %d", thisLoop, maxLoop));
+            if (thisLoop == maxLoop) {
+                // when maxLoop is 0, we loop forever, so not checking that case
+                // here
+                Log.d(LOG_TAG, "reached max loop count, stopping service");
+                stopService(intent);
+                return;
+            }
+            screenOn(context);
+            FileUtil.get().writeDateToFile(
+                    new File(Environment.getExternalStorageDirectory(), "wakeup-loop.txt"));
+            // calculate when device should be waken up
+            long atTime = SystemClock.elapsedRealtime() + wakeupInterval;
+            intent.putExtra(WakeLoopService.THIS_LOOP, thisLoop);
+            PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
+                    PendingIntent.FLAG_UPDATE_CURRENT);
+            // set alarm, which will be delivered in form of the wakeupIntent
+            am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, atTime, pi);
+        } else {
+            // cancel alarms
+            Log.d(LOG_TAG, "cancelling future alarms on request");
+            am.cancel(PendingIntent.getBroadcast(context, 0, intent, 0));
+        }
+    }
+
+    private void stopService(Intent i) {
+        Messenger msgr = i.getParcelableExtra(WakeLoopService.STOP_CALLBACK);
+        if (msgr == null) {
+            Log.e(LOG_TAG, "no stop service callback found, cannot stop");
+        } else {
+            Message msg = new Message();
+            msg.what = WakeLoopService.MSG_STOP_SERVICE;
+            try {
+                msgr.send(msg);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "ignored remoted exception while attempting to stop service", e);
+            }
+        }
+    }
+
+    private void screenOn(Context context) {
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        @SuppressWarnings("deprecation")
+        WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK |
+                PowerManager.ACQUIRE_CAUSES_WAKEUP, LOG_TAG);
+        wl.acquire(500);
+    }
+}
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 0e130f4..e7cde74 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -179,6 +179,8 @@
     void setVersionName(const char* val) { mVersionName = val; }
     bool getReplaceVersion() { return mReplaceVersion; }
     void setReplaceVersion(bool val) { mReplaceVersion = val; }
+    const android::String8& getRevisionCode() { return mRevisionCode; }
+    void setRevisionCode(const char* val) { mRevisionCode = android::String8(val); }
     const char* getCustomPackage() const { return mCustomPackage; }
     void setCustomPackage(const char* val) { mCustomPackage = val; }
     const char* getExtraPackages() const { return mExtraPackages; }
@@ -297,6 +299,7 @@
 
     android::String8 mFeatureOfPackage;
     android::String8 mFeatureAfterPackage;
+    android::String8 mRevisionCode;
     const char* mManifestMinSdkVersion;
     const char* mMinSdkVersion;
     const char* mTargetSdkVersion;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index e3a0200..e2e83e4 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -257,6 +257,11 @@
 
     assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));
 
+    ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "revisionCode");
+    if (revisionCodeIndex >= 0) {
+        bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string());
+    }
+
     String16 uses_sdk16("uses-sdk");
     while ((code=block.next()) != ResXMLTree::END_DOCUMENT
            && code != ResXMLTree::BAD_DOCUMENT) {
@@ -1075,6 +1080,14 @@
         return UNKNOWN_ERROR;
     }
 
+    // Add the 'revisionCode' attribute, which is set to the original revisionCode.
+    if (bundle->getRevisionCode().size() > 0) {
+        if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "revisionCode",
+                    bundle->getRevisionCode().string(), true, true)) {
+            return UNKNOWN_ERROR;
+        }
+    }
+
     // Add the 'split' attribute which describes the configurations included.
     String8 splitName("config.");
     splitName.append(split->getPackageSafeName());
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 6d03311..e87138c 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -4527,7 +4527,7 @@
         return NO_ERROR;
     }
 
-    Vector<key_value_pair_t<sp<XMLNode>, size_t> > attrsToRemove;
+    sp<XMLNode> newRoot = NULL;
 
     Vector<sp<XMLNode> > nodesToVisit;
     nodesToVisit.push(root);
@@ -4536,11 +4536,23 @@
         nodesToVisit.pop();
 
         const Vector<XMLNode::attribute_entry>& attrs = node->getAttributes();
-        const size_t attrCount = attrs.size();
-        for (size_t i = 0; i < attrCount; i++) {
+        for (size_t i = 0; i < attrs.size(); i++) {
             const XMLNode::attribute_entry& attr = attrs[i];
             if (isAttributeFromL(attr.nameResId)) {
-                attrsToRemove.add(key_value_pair_t<sp<XMLNode>, size_t>(node, i));
+                if (newRoot == NULL) {
+                    newRoot = root->clone();
+                }
+
+                if (bundle->getVerbose()) {
+                    SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
+                            "removing attribute %s%s%s from <%s>",
+                            String8(attr.ns).string(),
+                            (attr.ns.size() == 0 ? "" : ":"),
+                            String8(attr.name).string(),
+                            String8(node->getElementName()).string());
+                }
+                node->removeAttribute(i);
+                i--;
             }
         }
 
@@ -4552,7 +4564,7 @@
         }
     }
 
-    if (attrsToRemove.isEmpty()) {
+    if (newRoot == NULL) {
         return NO_ERROR;
     }
 
@@ -4562,12 +4574,8 @@
     // Look to see if we already have an overriding v21 configuration.
     sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),
             String16(target->getResourceType()), resourceName);
-    //if (cl == NULL) {
-    //    fprintf(stderr, "fuuuuck\n");
-    //}
     if (cl->getEntries().indexOfKey(newConfig) < 0) {
         // We don't have an overriding entry for v21, so we must duplicate this one.
-        sp<XMLNode> newRoot = root->clone();
         sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
                 AaptGroupEntry(newConfig), target->getResourceType());
         String8 resPath = String8::format("res/%s/%s",
@@ -4602,22 +4610,6 @@
         mWorkQueue.push(item);
     }
 
-    const size_t removeCount = attrsToRemove.size();
-    for (size_t i = 0; i < removeCount; i++) {
-        sp<XMLNode> node = attrsToRemove[i].key;
-        size_t attrIndex = attrsToRemove[i].value;
-        const XMLNode::attribute_entry& ae = node->getAttributes()[attrIndex];
-        if (bundle->getVerbose()) {
-            SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
-                    "removing attribute %s%s%s from <%s>",
-                    String8(ae.ns).string(),
-                    (ae.ns.size() == 0 ? "" : ":"),
-                    String8(ae.name).string(),
-                    String8(node->getElementName()).string());
-        }
-        node->removeAttribute(attrIndex);
-    }
-
     return NO_ERROR;
 }
 
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0457dda..12902bd 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -927,6 +927,42 @@
         }
     }
 
+    /** @hide
+     *  trim the scan Result Cache
+     * @param: number of entries to keep in the cache
+     */
+    public void trimScanResultsCache(int num) {
+        if (this.scanResultCache == null) {
+            return;
+        }
+        int currenSize = this.scanResultCache.size();
+        if (currenSize <= num) {
+            return; // Nothing to trim
+        }
+        ArrayList<ScanResult> list = new ArrayList<ScanResult>(this.scanResultCache.values());
+        if (list.size() != 0) {
+            // Sort by descending timestamp
+            Collections.sort(list, new Comparator() {
+                public int compare(Object o1, Object o2) {
+                    ScanResult a = (ScanResult)o1;
+                    ScanResult b = (ScanResult)o2;
+                    if (a.seen > b.seen) {
+                        return 1;
+                    }
+                    if (a.seen < b.seen) {
+                        return -1;
+                    }
+                    return a.BSSID.compareTo(b.BSSID);
+                }
+            });
+        }
+        for (int i = 0; i < currenSize - num ; i++) {
+            // Remove oldest results from scan cache
+            ScanResult result = list.get(i);
+            this.scanResultCache.remove(result.BSSID);
+        }
+    }
+
     /* @hide */
     private ArrayList<ScanResult> sortScanResults() {
         ArrayList<ScanResult> list = new ArrayList<ScanResult>(this.scanResultCache.values());