Merge "MidiService: Fix some concurrency problems"
diff --git a/Android.mk b/Android.mk
index 30318d6..1df2af3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -145,8 +145,6 @@
 	core/java/android/hardware/ICamera.aidl \
 	core/java/android/hardware/ICameraClient.aidl \
 	core/java/android/hardware/IConsumerIrService.aidl \
-	core/java/android/hardware/IProCameraUser.aidl \
-	core/java/android/hardware/IProCameraCallbacks.aidl \
 	core/java/android/hardware/camera2/ICameraDeviceUser.aidl \
 	core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
 	core/java/android/hardware/ISerialManager.aidl \
diff --git a/api/current.txt b/api/current.txt
index f7b668a..d8d8998 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -464,8 +464,8 @@
     field public static final int datePickerMode = 16843955; // 0x10104b3
     field public static final int datePickerStyle = 16843612; // 0x101035c
     field public static final int dateTextAppearance = 16843593; // 0x1010349
-    field public static final int dayOfWeekBackground = 16843924; // 0x1010494
-    field public static final int dayOfWeekTextAppearance = 16843925; // 0x1010495
+    field public static final deprecated int dayOfWeekBackground = 16843924; // 0x1010494
+    field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int delay = 16843212; // 0x10101cc
@@ -555,6 +555,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
+    field public static final int extractNativeLibs = 16844008; // 0x10104e8
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -587,7 +588,7 @@
     field public static final int flipInterval = 16843129; // 0x1010179
     field public static final int focusable = 16842970; // 0x10100da
     field public static final int focusableInTouchMode = 16842971; // 0x10100db
-    field public static final int focusedMonthDateColor = 16843587; // 0x1010343
+    field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343
     field public static final int fontFamily = 16843692; // 0x10103ac
     field public static final int fontFeatureSettings = 16843959; // 0x10104b7
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
@@ -651,9 +652,9 @@
     field public static final int hasCode = 16842764; // 0x101000c
     field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0
     field public static final int headerBackground = 16843055; // 0x101012f
-    field public static final int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
+    field public static final deprecated int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
     field public static final int headerDividersEnabled = 16843310; // 0x101022e
-    field public static final int headerMonthTextAppearance = 16843926; // 0x1010496
+    field public static final deprecated int headerMonthTextAppearance = 16843926; // 0x1010496
     field public static final int headerTimeTextAppearance = 16843935; // 0x101049f
     field public static final int headerYearTextAppearance = 16843928; // 0x1010498
     field public static final int height = 16843093; // 0x1010155
@@ -1094,8 +1095,8 @@
     field public static final int selectable = 16843238; // 0x10101e6
     field public static final int selectableItemBackground = 16843534; // 0x101030e
     field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
-    field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
-    field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
+    field public static final deprecated int selectedDateVerticalBar = 16843591; // 0x1010347
+    field public static final deprecated int selectedWeekBackgroundColor = 16843586; // 0x1010342
     field public static final int sessionService = 16843837; // 0x101043d
     field public static final int settingsActivity = 16843301; // 0x1010225
     field public static final int setupActivity = 16843766; // 0x10103f6
@@ -1114,8 +1115,8 @@
     field public static final int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
-    field public static final int showWeekNumber = 16843582; // 0x101033e
-    field public static final int shownWeekCount = 16843585; // 0x1010341
+    field public static final deprecated int showWeekNumber = 16843582; // 0x101033e
+    field public static final deprecated int shownWeekCount = 16843585; // 0x1010341
     field public static final int shrinkColumns = 16843082; // 0x101014a
     field public static final deprecated int singleLine = 16843101; // 0x101015d
     field public static final int singleUser = 16843711; // 0x10103bf
@@ -1352,7 +1353,7 @@
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
     field public static final int uncertainGestureColor = 16843382; // 0x1010276
-    field public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
+    field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
     field public static final int useDefaultMargins = 16843641; // 0x1010379
@@ -1394,8 +1395,8 @@
     field public static final int webTextViewStyle = 16843449; // 0x10102b9
     field public static final int webViewStyle = 16842885; // 0x1010085
     field public static final int weekDayTextAppearance = 16843592; // 0x1010348
-    field public static final int weekNumberColor = 16843589; // 0x1010345
-    field public static final int weekSeparatorLineColor = 16843590; // 0x1010346
+    field public static final deprecated int weekNumberColor = 16843589; // 0x1010345
+    field public static final deprecated int weekSeparatorLineColor = 16843590; // 0x1010346
     field public static final int weightSum = 16843048; // 0x1010128
     field public static final int widgetCategory = 16843716; // 0x10103c4
     field public static final int widgetLayout = 16843243; // 0x10101eb
@@ -1454,7 +1455,7 @@
     field public static final int xlargeScreens = 16843455; // 0x10102bf
     field public static final int y = 16842925; // 0x10100ad
     field public static final int yearListItemTextAppearance = 16843929; // 0x1010499
-    field public static final int yearListSelectorColor = 16843930; // 0x101049a
+    field public static final deprecated int yearListSelectorColor = 16843930; // 0x101049a
     field public static final int yesNoPreferenceStyle = 16842896; // 0x1010090
     field public static final int zAdjustment = 16843201; // 0x10101c1
   }
@@ -3431,6 +3432,7 @@
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public void onProvideAssistContent(android.app.AssistContent);
     method public void onProvideAssistData(android.os.Bundle);
+    method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method protected void onRestart();
     method protected void onRestoreInstanceState(android.os.Bundle);
     method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
@@ -3461,6 +3463,7 @@
     method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
+    method public final void requestPermissions(java.lang.String[], int);
     method public boolean requestVisibleBehind(boolean);
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
@@ -3977,22 +3980,25 @@
     method public int describeContents();
     method public android.content.ComponentName getActivityComponent();
     method public static android.app.AssistStructure getAssistStructure(android.os.Bundle);
-    method public void getWindowAt(int, android.app.AssistStructure.ViewNode);
-    method public int getWindowCount();
+    method public android.app.AssistStructure.WindowNode getWindowNodeAt(int);
+    method public int getWindowNodeCount();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String ASSIST_KEY = "android:assist_structure";
     field public static final android.os.Parcelable.Creator<android.app.AssistStructure> CREATOR;
   }
 
   public static class AssistStructure.ViewNode {
-    ctor public AssistStructure.ViewNode();
-    method public void getChildAt(int, android.app.AssistStructure.ViewNode);
+    method public android.app.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
-    method public java.lang.String getContentDescription();
+    method public java.lang.CharSequence getContentDescription();
     method public android.os.Bundle getExtras();
     method public int getHeight();
     method public java.lang.String getHint();
+    method public int getId();
+    method public java.lang.String getIdEntry();
+    method public java.lang.String getIdPackage();
+    method public java.lang.String getIdType();
     method public int getLeft();
     method public int getScrollX();
     method public int getScrollY();
@@ -4023,6 +4029,15 @@
     field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
   }
 
+  public static class AssistStructure.WindowNode {
+    method public int getHeight();
+    method public int getLeft();
+    method public android.app.AssistStructure.ViewNode getRootViewNode();
+    method public java.lang.CharSequence getTitle();
+    method public int getTop();
+    method public int getWidth();
+  }
+
   public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {
     ctor public DatePickerDialog(android.content.Context, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
     ctor public DatePickerDialog(android.content.Context, int, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
@@ -4303,6 +4318,7 @@
     method public void onOptionsMenuClosed(android.view.Menu);
     method public void onPause();
     method public void onPrepareOptionsMenu(android.view.Menu);
+    method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method public void onResume();
     method public void onSaveInstanceState(android.os.Bundle);
     method public void onStart();
@@ -4311,6 +4327,7 @@
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
     method public void registerForContextMenu(android.view.View);
+    method public final void requestPermissions(java.lang.String[], int);
     method public void setAllowEnterTransitionOverlap(boolean);
     method public void setAllowReturnTransitionOverlap(boolean);
     method public void setArguments(android.os.Bundle);
@@ -5663,12 +5680,18 @@
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
     field public static final java.lang.String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
     field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_DEVICE_ID = "android.app.extra.PROVISIONING_BT_DEVICE_ID";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_MAC_ADDRESS = "android.app.extra.PROVISIONING_BT_MAC_ADDRESS";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_USE_PROXY = "android.app.extra.PROVISIONING_BT_USE_PROXY";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_UUID = "android.app.extra.PROVISIONING_BT_UUID";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
     field public static final deprecated java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
@@ -7395,6 +7418,7 @@
     method public abstract int checkCallingPermission(java.lang.String);
     method public abstract int checkCallingUriPermission(android.net.Uri, int);
     method public abstract int checkPermission(java.lang.String, int, int);
+    method public abstract int checkSelfPermission(java.lang.String);
     method public abstract int checkUriPermission(android.net.Uri, int, int, int);
     method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public abstract deprecated void clearWallpaper() throws java.io.IOException;
@@ -7572,6 +7596,7 @@
     method public int checkCallingPermission(java.lang.String);
     method public int checkCallingUriPermission(android.net.Uri, int);
     method public int checkPermission(java.lang.String, int, int);
+    method public int checkSelfPermission(java.lang.String);
     method public int checkUriPermission(android.net.Uri, int, int, int);
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public deprecated void clearWallpaper() throws java.io.IOException;
@@ -8645,6 +8670,7 @@
     field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
     field public static final int FLAG_DEBUGGABLE = 2; // 0x2
     field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
+    field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
     field public static final int FLAG_FACTORY_TEST = 16; // 0x10
     field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
     field public static final int FLAG_HAS_CODE = 4; // 0x4
@@ -8824,7 +8850,6 @@
     field public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1; // 0x1
     field public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2; // 0x2
     field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
-    field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
     field public android.content.pm.ActivityInfo[] activities;
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public int baseRevisionCode;
@@ -14748,7 +14773,9 @@
     method public abstract android.media.Image.Plane[] getPlanes();
     method public abstract long getTimestamp();
     method public abstract int getWidth();
+    method public boolean isOpaque();
     method public void setCropRect(android.graphics.Rect);
+    method public void setTimestamp(long);
   }
 
   public static abstract class Image.Plane {
@@ -14766,7 +14793,9 @@
     method public int getMaxImages();
     method public android.view.Surface getSurface();
     method public int getWidth();
+    method public boolean isOpaque();
     method public static android.media.ImageReader newInstance(int, int, int, int);
+    method public static android.media.ImageReader newOpaqueInstance(int, int, int);
     method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
   }
 
@@ -14774,6 +14803,19 @@
     method public abstract void onImageAvailable(android.media.ImageReader);
   }
 
+  public class ImageWriter implements java.lang.AutoCloseable {
+    method public void close();
+    method public android.media.Image dequeueInputImage();
+    method public int getMaxImages();
+    method public static android.media.ImageWriter newInstance(android.view.Surface, int);
+    method public void queueInputImage(android.media.Image);
+    method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler);
+  }
+
+  public static abstract interface ImageWriter.ImageListener {
+    method public abstract void onInputImageReleased(android.media.ImageWriter);
+  }
+
   public class JetPlayer {
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
@@ -15206,6 +15248,9 @@
     field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
     field public static final java.lang.String PROPERTY_VENDOR = "vendor";
     field public static final java.lang.String PROPERTY_VERSION = "version";
+    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
+    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
+    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
   }
 
   public final class MediaDrm.CryptoSession {
@@ -15218,6 +15263,7 @@
   public static final class MediaDrm.KeyRequest {
     method public byte[] getData();
     method public java.lang.String getDefaultUrl();
+    method public int getRequestType();
   }
 
   public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -17249,6 +17295,10 @@
     field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
     field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
@@ -26726,8 +26776,11 @@
   public class AllocationAdapter extends android.renderscript.Allocation {
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+    method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+    method public void setArray(int, int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
+    method public void setX(int);
     method public void setY(int);
     method public void setZ(int);
   }
@@ -30154,6 +30207,7 @@
     method public int checkCallingPermission(java.lang.String);
     method public int checkCallingUriPermission(android.net.Uri, int);
     method public int checkPermission(java.lang.String, int, int);
+    method public int checkSelfPermission(java.lang.String);
     method public int checkUriPermission(android.net.Uri, int, int, int);
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public void clearWallpaper();
@@ -33241,6 +33295,7 @@
     method public java.lang.String getName();
     method public int getProductId();
     method public int getSources();
+    method public java.lang.String getUniqueId();
     method public int getVendorId();
     method public android.os.Vibrator getVibrator();
     method public boolean[] hasKeys(int...);
@@ -38131,34 +38186,34 @@
     method public long getDate();
     method public int getDateTextAppearance();
     method public int getFirstDayOfWeek();
-    method public int getFocusedMonthDateColor();
+    method public deprecated int getFocusedMonthDateColor();
     method public long getMaxDate();
     method public long getMinDate();
-    method public android.graphics.drawable.Drawable getSelectedDateVerticalBar();
-    method public int getSelectedWeekBackgroundColor();
+    method public deprecated android.graphics.drawable.Drawable getSelectedDateVerticalBar();
+    method public deprecated int getSelectedWeekBackgroundColor();
     method public boolean getShowWeekNumber();
-    method public int getShownWeekCount();
-    method public int getUnfocusedMonthDateColor();
+    method public deprecated int getShownWeekCount();
+    method public deprecated int getUnfocusedMonthDateColor();
     method public int getWeekDayTextAppearance();
-    method public int getWeekNumberColor();
-    method public int getWeekSeparatorLineColor();
+    method public deprecated int getWeekNumberColor();
+    method public deprecated int getWeekSeparatorLineColor();
     method public void setDate(long);
     method public void setDate(long, boolean, boolean);
     method public void setDateTextAppearance(int);
     method public void setFirstDayOfWeek(int);
-    method public void setFocusedMonthDateColor(int);
+    method public deprecated void setFocusedMonthDateColor(int);
     method public void setMaxDate(long);
     method public void setMinDate(long);
     method public void setOnDateChangeListener(android.widget.CalendarView.OnDateChangeListener);
-    method public void setSelectedDateVerticalBar(int);
-    method public void setSelectedDateVerticalBar(android.graphics.drawable.Drawable);
-    method public void setSelectedWeekBackgroundColor(int);
+    method public deprecated void setSelectedDateVerticalBar(int);
+    method public deprecated void setSelectedDateVerticalBar(android.graphics.drawable.Drawable);
+    method public deprecated void setSelectedWeekBackgroundColor(int);
     method public void setShowWeekNumber(boolean);
-    method public void setShownWeekCount(int);
-    method public void setUnfocusedMonthDateColor(int);
+    method public deprecated void setShownWeekCount(int);
+    method public deprecated void setUnfocusedMonthDateColor(int);
     method public void setWeekDayTextAppearance(int);
-    method public void setWeekNumberColor(int);
-    method public void setWeekSeparatorLineColor(int);
+    method public deprecated void setWeekNumberColor(int);
+    method public deprecated void setWeekSeparatorLineColor(int);
   }
 
   public static abstract interface CalendarView.OnDateChangeListener {
@@ -39091,7 +39146,7 @@
     method public void setTouchInterceptor(android.view.View.OnTouchListener);
     method public void setTouchable(boolean);
     method public void setWidth(int);
-    method public void setWindowLayoutMode(int, int);
+    method public deprecated void setWindowLayoutMode(int, int);
     method public void showAsDropDown(android.view.View);
     method public void showAsDropDown(android.view.View, int, int);
     method public void showAsDropDown(android.view.View, int, int, int);
diff --git a/api/removed.txt b/api/removed.txt
index 1b209a9..c2b9d3e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,3 +1,11 @@
+package android.content.pm {
+
+  public class PackageInfo implements android.os.Parcelable {
+    field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
+  }
+
+}
+
 package android.media {
 
   public class AudioFormat {
diff --git a/api/system-current.txt b/api/system-current.txt
index 10298e4..71474a3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -536,8 +536,8 @@
     field public static final int datePickerMode = 16843955; // 0x10104b3
     field public static final int datePickerStyle = 16843612; // 0x101035c
     field public static final int dateTextAppearance = 16843593; // 0x1010349
-    field public static final int dayOfWeekBackground = 16843924; // 0x1010494
-    field public static final int dayOfWeekTextAppearance = 16843925; // 0x1010495
+    field public static final deprecated int dayOfWeekBackground = 16843924; // 0x1010494
+    field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int delay = 16843212; // 0x10101cc
@@ -627,6 +627,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
+    field public static final int extractNativeLibs = 16844008; // 0x10104e8
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -659,7 +660,7 @@
     field public static final int flipInterval = 16843129; // 0x1010179
     field public static final int focusable = 16842970; // 0x10100da
     field public static final int focusableInTouchMode = 16842971; // 0x10100db
-    field public static final int focusedMonthDateColor = 16843587; // 0x1010343
+    field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343
     field public static final int fontFamily = 16843692; // 0x10103ac
     field public static final int fontFeatureSettings = 16843959; // 0x10104b7
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
@@ -723,9 +724,9 @@
     field public static final int hasCode = 16842764; // 0x101000c
     field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0
     field public static final int headerBackground = 16843055; // 0x101012f
-    field public static final int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
+    field public static final deprecated int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
     field public static final int headerDividersEnabled = 16843310; // 0x101022e
-    field public static final int headerMonthTextAppearance = 16843926; // 0x1010496
+    field public static final deprecated int headerMonthTextAppearance = 16843926; // 0x1010496
     field public static final int headerTimeTextAppearance = 16843935; // 0x101049f
     field public static final int headerYearTextAppearance = 16843928; // 0x1010498
     field public static final int height = 16843093; // 0x1010155
@@ -1170,8 +1171,8 @@
     field public static final int selectable = 16843238; // 0x10101e6
     field public static final int selectableItemBackground = 16843534; // 0x101030e
     field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
-    field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
-    field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
+    field public static final deprecated int selectedDateVerticalBar = 16843591; // 0x1010347
+    field public static final deprecated int selectedWeekBackgroundColor = 16843586; // 0x1010342
     field public static final int sessionService = 16843837; // 0x101043d
     field public static final int settingsActivity = 16843301; // 0x1010225
     field public static final int setupActivity = 16843766; // 0x10103f6
@@ -1190,8 +1191,8 @@
     field public static final int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
-    field public static final int showWeekNumber = 16843582; // 0x101033e
-    field public static final int shownWeekCount = 16843585; // 0x1010341
+    field public static final deprecated int showWeekNumber = 16843582; // 0x101033e
+    field public static final deprecated int shownWeekCount = 16843585; // 0x1010341
     field public static final int shrinkColumns = 16843082; // 0x101014a
     field public static final deprecated int singleLine = 16843101; // 0x101015d
     field public static final int singleUser = 16843711; // 0x10103bf
@@ -1428,7 +1429,7 @@
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
     field public static final int uncertainGestureColor = 16843382; // 0x1010276
-    field public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
+    field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
     field public static final int useDefaultMargins = 16843641; // 0x1010379
@@ -1470,8 +1471,8 @@
     field public static final int webTextViewStyle = 16843449; // 0x10102b9
     field public static final int webViewStyle = 16842885; // 0x1010085
     field public static final int weekDayTextAppearance = 16843592; // 0x1010348
-    field public static final int weekNumberColor = 16843589; // 0x1010345
-    field public static final int weekSeparatorLineColor = 16843590; // 0x1010346
+    field public static final deprecated int weekNumberColor = 16843589; // 0x1010345
+    field public static final deprecated int weekSeparatorLineColor = 16843590; // 0x1010346
     field public static final int weightSum = 16843048; // 0x1010128
     field public static final int widgetCategory = 16843716; // 0x10103c4
     field public static final int widgetLayout = 16843243; // 0x10101eb
@@ -1530,7 +1531,7 @@
     field public static final int xlargeScreens = 16843455; // 0x10102bf
     field public static final int y = 16842925; // 0x10100ad
     field public static final int yearListItemTextAppearance = 16843929; // 0x1010499
-    field public static final int yearListSelectorColor = 16843930; // 0x101049a
+    field public static final deprecated int yearListSelectorColor = 16843930; // 0x101049a
     field public static final int yesNoPreferenceStyle = 16842896; // 0x1010090
     field public static final int zAdjustment = 16843201; // 0x10101c1
   }
@@ -3514,6 +3515,7 @@
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public void onProvideAssistContent(android.app.AssistContent);
     method public void onProvideAssistData(android.os.Bundle);
+    method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method protected void onRestart();
     method protected void onRestoreInstanceState(android.os.Bundle);
     method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
@@ -3544,6 +3546,7 @@
     method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
+    method public final void requestPermissions(java.lang.String[], int);
     method public boolean requestVisibleBehind(boolean);
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
@@ -4067,22 +4070,25 @@
     method public int describeContents();
     method public android.content.ComponentName getActivityComponent();
     method public static android.app.AssistStructure getAssistStructure(android.os.Bundle);
-    method public void getWindowAt(int, android.app.AssistStructure.ViewNode);
-    method public int getWindowCount();
+    method public android.app.AssistStructure.WindowNode getWindowNodeAt(int);
+    method public int getWindowNodeCount();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String ASSIST_KEY = "android:assist_structure";
     field public static final android.os.Parcelable.Creator<android.app.AssistStructure> CREATOR;
   }
 
   public static class AssistStructure.ViewNode {
-    ctor public AssistStructure.ViewNode();
-    method public void getChildAt(int, android.app.AssistStructure.ViewNode);
+    method public android.app.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
-    method public java.lang.String getContentDescription();
+    method public java.lang.CharSequence getContentDescription();
     method public android.os.Bundle getExtras();
     method public int getHeight();
     method public java.lang.String getHint();
+    method public int getId();
+    method public java.lang.String getIdEntry();
+    method public java.lang.String getIdPackage();
+    method public java.lang.String getIdType();
     method public int getLeft();
     method public int getScrollX();
     method public int getScrollY();
@@ -4113,6 +4119,15 @@
     field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
   }
 
+  public static class AssistStructure.WindowNode {
+    method public int getHeight();
+    method public int getLeft();
+    method public android.app.AssistStructure.ViewNode getRootViewNode();
+    method public java.lang.CharSequence getTitle();
+    method public int getTop();
+    method public int getWidth();
+  }
+
   public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {
     ctor public DatePickerDialog(android.content.Context, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
     ctor public DatePickerDialog(android.content.Context, int, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
@@ -4393,6 +4408,7 @@
     method public void onOptionsMenuClosed(android.view.Menu);
     method public void onPause();
     method public void onPrepareOptionsMenu(android.view.Menu);
+    method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method public void onResume();
     method public void onSaveInstanceState(android.os.Bundle);
     method public void onStart();
@@ -4401,6 +4417,7 @@
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
     method public void registerForContextMenu(android.view.View);
+    method public final void requestPermissions(java.lang.String[], int);
     method public void setAllowEnterTransitionOverlap(boolean);
     method public void setAllowReturnTransitionOverlap(boolean);
     method public void setArguments(android.os.Bundle);
@@ -5767,12 +5784,18 @@
     field public static final java.lang.String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
     field public static final java.lang.String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
     field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_DEVICE_ID = "android.app.extra.PROVISIONING_BT_DEVICE_ID";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_MAC_ADDRESS = "android.app.extra.PROVISIONING_BT_MAC_ADDRESS";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_USE_PROXY = "android.app.extra.PROVISIONING_BT_USE_PROXY";
+    field public static final java.lang.String EXTRA_PROVISIONING_BT_UUID = "android.app.extra.PROVISIONING_BT_UUID";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
     field public static final deprecated java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
     field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
@@ -7601,6 +7624,7 @@
     method public abstract int checkCallingPermission(java.lang.String);
     method public abstract int checkCallingUriPermission(android.net.Uri, int);
     method public abstract int checkPermission(java.lang.String, int, int);
+    method public abstract int checkSelfPermission(java.lang.String);
     method public abstract int checkUriPermission(android.net.Uri, int, int, int);
     method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public abstract deprecated void clearWallpaper() throws java.io.IOException;
@@ -7784,6 +7808,7 @@
     method public int checkCallingPermission(java.lang.String);
     method public int checkCallingUriPermission(android.net.Uri, int);
     method public int checkPermission(java.lang.String, int, int);
+    method public int checkSelfPermission(java.lang.String);
     method public int checkUriPermission(android.net.Uri, int, int, int);
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public deprecated void clearWallpaper() throws java.io.IOException;
@@ -8860,6 +8885,7 @@
     field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
     field public static final int FLAG_DEBUGGABLE = 2; // 0x2
     field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
+    field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
     field public static final int FLAG_FACTORY_TEST = 16; // 0x10
     field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
     field public static final int FLAG_HAS_CODE = 4; // 0x4
@@ -9064,7 +9090,6 @@
     field public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1; // 0x1
     field public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2; // 0x2
     field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
-    field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
     field public android.content.pm.ActivityInfo[] activities;
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public int baseRevisionCode;
@@ -9264,6 +9289,7 @@
     method public abstract android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle);
     method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public abstract void grantPermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -9279,16 +9305,20 @@
     method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int);
     method public abstract android.content.pm.ProviderInfo resolveContentProvider(java.lang.String, int);
     method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
+    method public abstract void revokePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
     method public abstract void verifyPendingInstall(int, int);
+    field public static final java.lang.String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
     field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
     field public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4; // 0x4
     field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3
     field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1
     field public static final int DONT_KILL_APP = 1; // 0x1
+    field public static final java.lang.String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
+    field public static final java.lang.String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
     field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
     field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
     field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
@@ -15938,7 +15968,9 @@
     method public abstract android.media.Image.Plane[] getPlanes();
     method public abstract long getTimestamp();
     method public abstract int getWidth();
+    method public boolean isOpaque();
     method public void setCropRect(android.graphics.Rect);
+    method public void setTimestamp(long);
   }
 
   public static abstract class Image.Plane {
@@ -15956,7 +15988,9 @@
     method public int getMaxImages();
     method public android.view.Surface getSurface();
     method public int getWidth();
+    method public boolean isOpaque();
     method public static android.media.ImageReader newInstance(int, int, int, int);
+    method public static android.media.ImageReader newOpaqueInstance(int, int, int);
     method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
   }
 
@@ -15964,6 +15998,19 @@
     method public abstract void onImageAvailable(android.media.ImageReader);
   }
 
+  public class ImageWriter implements java.lang.AutoCloseable {
+    method public void close();
+    method public android.media.Image dequeueInputImage();
+    method public int getMaxImages();
+    method public static android.media.ImageWriter newInstance(android.view.Surface, int);
+    method public void queueInputImage(android.media.Image);
+    method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler);
+  }
+
+  public static abstract interface ImageWriter.ImageListener {
+    method public abstract void onInputImageReleased(android.media.ImageWriter);
+  }
+
   public class JetPlayer {
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
@@ -16397,6 +16444,9 @@
     field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
     field public static final java.lang.String PROPERTY_VENDOR = "vendor";
     field public static final java.lang.String PROPERTY_VERSION = "version";
+    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
+    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
+    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
   }
 
   public final class MediaDrm.CryptoSession {
@@ -16409,6 +16459,7 @@
   public static final class MediaDrm.KeyRequest {
     method public byte[] getData();
     method public java.lang.String getDefaultUrl();
+    method public int getRequestType();
   }
 
   public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -18520,6 +18571,10 @@
     field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
     field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
@@ -28524,8 +28579,11 @@
   public class AllocationAdapter extends android.renderscript.Allocation {
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+    method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+    method public void setArray(int, int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
+    method public void setX(int);
     method public void setY(int);
     method public void setZ(int);
   }
@@ -32513,6 +32571,7 @@
     method public int checkCallingPermission(java.lang.String);
     method public int checkCallingUriPermission(android.net.Uri, int);
     method public int checkPermission(java.lang.String, int, int);
+    method public int checkSelfPermission(java.lang.String);
     method public int checkUriPermission(android.net.Uri, int, int, int);
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public void clearWallpaper();
@@ -35600,6 +35659,7 @@
     method public java.lang.String getName();
     method public int getProductId();
     method public int getSources();
+    method public java.lang.String getUniqueId();
     method public int getVendorId();
     method public android.os.Vibrator getVibrator();
     method public boolean[] hasKeys(int...);
@@ -40791,34 +40851,34 @@
     method public long getDate();
     method public int getDateTextAppearance();
     method public int getFirstDayOfWeek();
-    method public int getFocusedMonthDateColor();
+    method public deprecated int getFocusedMonthDateColor();
     method public long getMaxDate();
     method public long getMinDate();
-    method public android.graphics.drawable.Drawable getSelectedDateVerticalBar();
-    method public int getSelectedWeekBackgroundColor();
+    method public deprecated android.graphics.drawable.Drawable getSelectedDateVerticalBar();
+    method public deprecated int getSelectedWeekBackgroundColor();
     method public boolean getShowWeekNumber();
-    method public int getShownWeekCount();
-    method public int getUnfocusedMonthDateColor();
+    method public deprecated int getShownWeekCount();
+    method public deprecated int getUnfocusedMonthDateColor();
     method public int getWeekDayTextAppearance();
-    method public int getWeekNumberColor();
-    method public int getWeekSeparatorLineColor();
+    method public deprecated int getWeekNumberColor();
+    method public deprecated int getWeekSeparatorLineColor();
     method public void setDate(long);
     method public void setDate(long, boolean, boolean);
     method public void setDateTextAppearance(int);
     method public void setFirstDayOfWeek(int);
-    method public void setFocusedMonthDateColor(int);
+    method public deprecated void setFocusedMonthDateColor(int);
     method public void setMaxDate(long);
     method public void setMinDate(long);
     method public void setOnDateChangeListener(android.widget.CalendarView.OnDateChangeListener);
-    method public void setSelectedDateVerticalBar(int);
-    method public void setSelectedDateVerticalBar(android.graphics.drawable.Drawable);
-    method public void setSelectedWeekBackgroundColor(int);
+    method public deprecated void setSelectedDateVerticalBar(int);
+    method public deprecated void setSelectedDateVerticalBar(android.graphics.drawable.Drawable);
+    method public deprecated void setSelectedWeekBackgroundColor(int);
     method public void setShowWeekNumber(boolean);
-    method public void setShownWeekCount(int);
-    method public void setUnfocusedMonthDateColor(int);
+    method public deprecated void setShownWeekCount(int);
+    method public deprecated void setUnfocusedMonthDateColor(int);
     method public void setWeekDayTextAppearance(int);
-    method public void setWeekNumberColor(int);
-    method public void setWeekSeparatorLineColor(int);
+    method public deprecated void setWeekNumberColor(int);
+    method public deprecated void setWeekSeparatorLineColor(int);
   }
 
   public static abstract interface CalendarView.OnDateChangeListener {
@@ -41751,7 +41811,7 @@
     method public void setTouchInterceptor(android.view.View.OnTouchListener);
     method public void setTouchable(boolean);
     method public void setWidth(int);
-    method public void setWindowLayoutMode(int, int);
+    method public deprecated void setWindowLayoutMode(int, int);
     method public void showAsDropDown(android.view.View);
     method public void showAsDropDown(android.view.View, int, int);
     method public void showAsDropDown(android.view.View, int, int, int);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 1b209a9..c2b9d3e 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -1,3 +1,11 @@
+package android.content.pm {
+
+  public class PackageInfo implements android.os.Parcelable {
+    field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
+  }
+
+}
+
 package android.media {
 
   public class AudioFormat {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index c48a618..89dd079 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -892,6 +892,8 @@
                 installFlags |= PackageManager.INSTALL_INTERNAL;
             } else if (opt.equals("-d")) {
                 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            } else if (opt.equals("-g")) {
+                installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
             } else if (opt.equals("--originating-uri")) {
                 originatingUriString = nextOptionData();
                 if (originatingUriString == null) {
@@ -1517,6 +1519,15 @@
     }
 
     private int runGrantRevokePermission(boolean grant) {
+        int userId = UserHandle.USER_CURRENT;
+
+        String opt = null;
+        while ((opt = nextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = Integer.parseInt(nextArg());
+            }
+        }
+
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified");
@@ -1529,11 +1540,12 @@
             showUsage();
             return 1;
         }
+
         try {
             if (grant) {
-                mPm.grantPermission(pkg, perm);
+                mPm.grantPermission(pkg, perm, userId);
             } else {
-                mPm.revokePermission(pkg, perm);
+                mPm.revokePermission(pkg, perm, userId);
             }
             return 0;
         } catch (RemoteException e) {
@@ -1815,8 +1827,8 @@
         System.err.println("       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm hide [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
-        System.err.println("       pm grant PACKAGE PERMISSION");
-        System.err.println("       pm revoke PACKAGE PERMISSION");
+        System.err.println("       pm grant [--user USER_ID] PACKAGE PERMISSION");
+        System.err.println("       pm revoke [--user USER_ID] PACKAGE PERMISSION");
         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
         System.err.println("       pm get-install-location");
         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
@@ -1868,6 +1880,7 @@
         System.err.println("    -f: install application on internal flash");
         System.err.println("    -d: allow version code downgrade");
         System.err.println("    -p: partial application install");
+        System.err.println("    -g: grant all runtime permissions");
         System.err.println("    -S: size in bytes of entire session");
         System.err.println("");
         System.err.println("pm install-write: write a package into existing session; path may");
@@ -1889,8 +1902,9 @@
         System.err.println("  as \"package/class\").");
         System.err.println("");
         System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
-        System.err.println("  to applications.  Only optional permissions the application has");
-        System.err.println("  declared can be granted or revoked.");
+        System.err.println("    to apps. The permissions must be declared as used in the app's");
+        System.err.println("    manifest, be runtime permissions (protection level dangerous),");
+        System.err.println("    and the app targeting SDK greater than Lollipop MR1.");
         System.err.println("");
         System.err.println("pm get-install-location: returns the current install location.");
         System.err.println("    0 [auto]: Let system decide the best location");
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7fcbe35..b5817df5 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3726,6 +3726,95 @@
     }
 
     /**
+     * Requests permissions to be granted to this application. These permissions
+     * must be requested in your manifest, they should not be granted to your app,
+     * and they should have protection level {@link android.content.pm.PermissionInfo
+     * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by
+     * the platform or a third-party app.
+     * <p>
+     * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
+     * are granted at install time if requested in the manifest. Signature permissions
+     * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
+     * install time if requested in the manifest and the signature of your app matches
+     * the signature of the app declaring the permissions.
+     * </p>
+     * <p>
+     * If your app does not have the requested permissions the user will be presented
+     * with UI for accepting them. After the user has accepted or rejected the
+     * requested permissions you will receive a callback on {@link
+     * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
+     * permissions were granted or not.
+     * </p>
+     * <p>
+     * Note that requesting a permission does not guarantee it will be granted and
+     * your app should be able to run without having this permission.
+     * </p>
+     * <p>
+     * This method may start an activity allowing the user to choose which permissions
+     * to grant and which to reject. Hence, you should be prepared that your activity
+     * may be paused and resumed. Further, granting some permissions may require
+     * a restart of you application. In such a case, the system will recreate the
+     * activity stack before delivering the result to {@link
+     * #onRequestPermissionsResult(int, String[], int[])}.
+     * </p>
+     * <p>
+     * When checking whether you have a permission you should use {@link
+     * #checkSelfPermission(String)}.
+     * </p>
+     * <p>
+     * A sample permissions request looks like this:
+     * </p>
+     * <code><pre><p>
+     * private void showContacts() {
+     *     if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+     *             != PackageManager.PERMISSION_GRANTED) {
+     *         requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+     *                 PERMISSIONS_REQUEST_READ_CONTACTS);
+     *     } else {
+     *         doShowContacts();
+     *     }
+     * }
+     *
+     * {@literal @}Override
+     * public void onRequestPermissionsResult(int requestCode, String[] permissions,
+     *         int[] grantResults) {
+     *     if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS
+     *             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+     *         showContacts();
+     *     }
+     * }
+     * </code></pre></p>
+     *
+     * @param permissions The requested permissions.
+     * @param requestCode Application specific request code to match with a result
+     *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
+     *
+     * @see #onRequestPermissionsResult(int, String[], int[])
+     * @see #checkSelfPermission(String)
+     */
+    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
+        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
+        startActivityForResult(intent, requestCode);
+    }
+
+    /**
+     * Callback for the result from requesting permissions. This method
+     * is invoked for every call on {@link #requestPermissions(String[], int)}.
+     *
+     * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
+     * @param permissions The requested permissions. Never null.
+     * @param grantResults The grant results for the corresponding permissions
+     *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
+     *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
+     *
+     * @see #requestPermissions(String[], int)
+     */
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+            @NonNull int[] grantResults) {
+        /* callback - no nothing */
+    }
+
+    /**
      * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
      * with no options.
      *
@@ -6269,11 +6358,19 @@
             + ", resCode=" + resultCode + ", data=" + data);
         mFragments.noteStateNotSaved();
         if (who == null) {
-            onActivityResult(requestCode, resultCode, data);
+            if (isRequestPermissionResult(data)) {
+                dispatchRequestPermissionsResult(requestCode, data);
+            } else {
+                onActivityResult(requestCode, resultCode, data);
+            }
         } else {
             Fragment frag = mFragments.findFragmentByWho(who);
             if (frag != null) {
-                frag.onActivityResult(requestCode, resultCode, data);
+                if (isRequestPermissionResult(data)) {
+                    dispatchRequestPermissionsResultToFragment(requestCode, data, frag);
+                } else {
+                    frag.onActivityResult(requestCode, resultCode, data);
+                }
             }
         }
     }
@@ -6343,4 +6440,26 @@
          */
         public void onTranslucentConversionComplete(boolean drawComplete);
     }
+
+    private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
+        String[] permissions = data.getStringArrayExtra(
+                PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
+        final int[] grantResults = data.getIntArrayExtra(
+                PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
+        onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
+    private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data,
+            Fragment fragement) {
+        String[] permissions = data.getStringArrayExtra(
+                PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
+        final int[] grantResults = data.getIntArrayExtra(
+                PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
+        fragement.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
+    private static boolean isRequestPermissionResult(Intent intent) {
+        return intent != null
+                && PackageManager.ACTION_REQUEST_PERMISSIONS.equals(intent.getAction());
+    }
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 29b024ac..d143f8b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2493,7 +2493,8 @@
     public static int checkComponentPermission(String permission, int uid,
             int owningUid, boolean exported) {
         // Root, system server get to do everything.
-        if (uid == 0 || uid == Process.SYSTEM_UID) {
+        final int appId = UserHandle.getAppId(uid);
+        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
             return PackageManager.PERMISSION_GRANTED;
         }
         // Isolated processes don't get any permissions.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7b8ec74..4880db1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -74,6 +74,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.security.NetworkSecurityPolicy;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -4480,6 +4481,9 @@
             StrictMode.enableDeathOnNetwork();
         }
 
+        NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
+                (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
+
         if (data.debugMode != IApplicationThread.DEBUG_OFF) {
             // XXX should have option to change the port.
             Debug.changeDebugPort(8100);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9f81670..6d74905 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -81,7 +81,6 @@
 /*package*/
 final class ApplicationPackageManager extends PackageManager {
     private static final String TAG = "ApplicationPackageManager";
-    private final static boolean DEBUG = false;
     private final static boolean DEBUG_ICONS = false;
 
     // Default flags to use with PackageManager when no flags are given.
@@ -186,8 +185,8 @@
     public int[] getPackageGids(String packageName)
             throws NameNotFoundException {
         try {
-            int[] gids = mPM.getPackageGids(packageName);
-            if (gids == null || gids.length > 0) {
+            int[] gids = mPM.getPackageGids(packageName, mContext.getUserId());
+            if (gids != null) {
                 return gids;
             }
         } catch (RemoteException e) {
@@ -398,7 +397,7 @@
     @Override
     public int checkPermission(String permName, String pkgName) {
         try {
-            return mPM.checkPermission(permName, pkgName);
+            return mPM.checkPermission(permName, pkgName, mContext.getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
@@ -432,18 +431,18 @@
     }
 
     @Override
-    public void grantPermission(String packageName, String permissionName) {
+    public void grantPermission(String packageName, String permissionName, UserHandle user) {
         try {
-            mPM.grantPermission(packageName, permissionName);
+            mPM.grantPermission(packageName, permissionName, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
     }
 
     @Override
-    public void revokePermission(String packageName, String permissionName) {
+    public void revokePermission(String packageName, String permissionName, UserHandle user) {
         try {
-            mPM.revokePermission(packageName, permissionName);
+            mPM.revokePermission(packageName, permissionName, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index 25153fc5..c435ccb 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.content.ComponentName;
+import android.content.res.Resources;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
@@ -53,7 +54,7 @@
 
     final ComponentName mActivityComponent;
 
-    final ArrayList<ViewNodeImpl> mRootViews = new ArrayList<>();
+    final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
 
     ViewAssistStructureImpl mTmpViewAssistStructureImpl = new ViewAssistStructureImpl();
     Bundle mTmpExtras = new Bundle();
@@ -178,7 +179,91 @@
         }
     }
 
-    final static class ViewNodeImpl {
+    /**
+     * Describes a window in the assist data.
+     */
+    static public class WindowNode {
+        final int mX;
+        final int mY;
+        final int mWidth;
+        final int mHeight;
+        final CharSequence mTitle;
+        final ViewNode mRoot;
+
+        WindowNode(AssistStructure assist, ViewRootImpl root) {
+            View view = root.getView();
+            Rect rect = new Rect();
+            view.getBoundsOnScreen(rect);
+            mX = rect.left - view.getLeft();
+            mY = rect.top - view.getTop();
+            mWidth = rect.width();
+            mHeight = rect.height();
+            mTitle = root.getTitle();
+            mRoot = new ViewNode(assist, view);
+        }
+
+        WindowNode(Parcel in, PooledStringReader preader) {
+            mX = in.readInt();
+            mY = in.readInt();
+            mWidth = in.readInt();
+            mHeight = in.readInt();
+            mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            mRoot = new ViewNode(in, preader);
+        }
+
+        void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+            out.writeInt(mX);
+            out.writeInt(mY);
+            out.writeInt(mWidth);
+            out.writeInt(mHeight);
+            TextUtils.writeToParcel(mTitle, out, 0);
+            mRoot.writeToParcel(out, pwriter);
+        }
+
+        public int getLeft() {
+            return mX;
+        }
+
+        public int getTop() {
+            return mY;
+        }
+
+        public int getWidth() {
+            return mWidth;
+        }
+
+        public int getHeight() {
+            return mHeight;
+        }
+
+        public CharSequence getTitle() {
+            return mTitle;
+        }
+
+        public ViewNode getRootViewNode() {
+            return mRoot;
+        }
+    }
+
+    /**
+     * Describes a single view in the assist data.
+     */
+    static public class ViewNode {
+        /**
+         * Magic value for text color that has not been defined, which is very unlikely
+         * to be confused with a real text color.
+         */
+        public static final int TEXT_COLOR_UNDEFINED = 1;
+
+        public static final int TEXT_STYLE_BOLD = 1<<0;
+        public static final int TEXT_STYLE_ITALIC = 1<<1;
+        public static final int TEXT_STYLE_UNDERLINE = 1<<2;
+        public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
+
+        final int mId;
+        final String mIdPackage;
+        final String mIdType;
+        final String mIdEntry;
         final int mX;
         final int mY;
         final int mScrollX;
@@ -201,17 +286,34 @@
         final int mFlags;
 
         final String mClassName;
-        final String mContentDescription;
+        final CharSequence mContentDescription;
 
         final ViewNodeTextImpl mText;
         final Bundle mExtras;
 
-        final ViewNodeImpl[] mChildren;
+        final ViewNode[] mChildren;
 
-        ViewNodeImpl(AssistStructure assistStructure, View view, int left, int top,
-                CharSequence contentDescription) {
-            mX = left;
-            mY = top;
+        ViewNode(AssistStructure assistStructure, View view) {
+            mId = view.getId();
+            if (mId > 0 && (mId&0xff000000) != 0 && (mId&0x00ff0000) != 0
+                    && (mId&0x0000ffff) != 0) {
+                String pkg, type, entry;
+                try {
+                    Resources res = view.getResources();
+                    entry = res.getResourceEntryName(mId);
+                    type = res.getResourceTypeName(mId);
+                    pkg = res.getResourcePackageName(mId);
+                } catch (Resources.NotFoundException e) {
+                    entry = type = pkg = null;
+                }
+                mIdPackage = pkg;
+                mIdType = type;
+                mIdEntry = entry;
+            } else {
+                mIdPackage = mIdType = mIdEntry = null;
+            }
+            mX = view.getLeft();
+            mY = view.getTop();
             mScrollX = view.getScrollX();
             mScrollY = view.getScrollY();
             mWidth = view.getWidth();
@@ -249,7 +351,7 @@
             }
             mFlags = flags;
             mClassName = view.getAccessibilityClassName().toString();
-            mContentDescription = contentDescription != null ? contentDescription.toString() : null;
+            mContentDescription = view.getContentDescription();
             final ViewAssistStructureImpl viewData = assistStructure.mTmpViewAssistStructureImpl;
             final Bundle extras = assistStructure.mTmpExtras;
             view.onProvideAssistStructure(viewData, extras);
@@ -269,9 +371,9 @@
                 ViewGroup vg = (ViewGroup)view;
                 final int NCHILDREN = vg.getChildCount();
                 if (NCHILDREN > 0) {
-                    mChildren = new ViewNodeImpl[NCHILDREN];
+                    mChildren = new ViewNode[NCHILDREN];
                     for (int i=0; i<NCHILDREN; i++) {
-                        mChildren[i] = new ViewNodeImpl(assistStructure, vg.getChildAt(i));
+                        mChildren[i] = new ViewNode(assistStructure, vg.getChildAt(i));
                     }
                 } else {
                     mChildren = null;
@@ -281,11 +383,19 @@
             }
         }
 
-        ViewNodeImpl(AssistStructure assistStructure, View view) {
-            this(assistStructure, view, view.getLeft(), view.getTop(), view.getContentDescription());
-        }
-
-        ViewNodeImpl(Parcel in, PooledStringReader preader) {
+        ViewNode(Parcel in, PooledStringReader preader) {
+            mId = in.readInt();
+            if (mId != 0) {
+                mIdEntry = preader.readString();
+                if (mIdEntry != null) {
+                    mIdType = preader.readString();
+                    mIdPackage = preader.readString();
+                } else {
+                    mIdPackage = mIdType = null;
+                }
+            } else {
+                mIdPackage = mIdType = mIdEntry = null;
+            }
             mX = in.readInt();
             mY = in.readInt();
             mScrollX = in.readInt();
@@ -294,7 +404,7 @@
             mHeight = in.readInt();
             mFlags = in.readInt();
             mClassName = preader.readString();
-            mContentDescription = in.readString();
+            mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             if (in.readInt() != 0) {
                 mText = new ViewNodeTextImpl(in);
             } else {
@@ -303,9 +413,9 @@
             mExtras = in.readBundle();
             final int NCHILDREN = in.readInt();
             if (NCHILDREN > 0) {
-                mChildren = new ViewNodeImpl[NCHILDREN];
+                mChildren = new ViewNode[NCHILDREN];
                 for (int i=0; i<NCHILDREN; i++) {
-                    mChildren[i] = new ViewNodeImpl(in, preader);
+                    mChildren[i] = new ViewNode(in, preader);
                 }
             } else {
                 mChildren = null;
@@ -313,6 +423,14 @@
         }
 
         void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+            out.writeInt(mId);
+            if (mId != 0) {
+                pwriter.writeString(mIdEntry);
+                if (mIdEntry != null) {
+                    pwriter.writeString(mIdType);
+                    pwriter.writeString(mIdPackage);
+                }
+            }
             out.writeInt(mX);
             out.writeInt(mY);
             out.writeInt(mScrollX);
@@ -321,7 +439,7 @@
             out.writeInt(mHeight);
             out.writeInt(mFlags);
             pwriter.writeString(mClassName);
-            out.writeString(mContentDescription);
+            TextUtils.writeToParcel(mContentDescription, out, 0);
             if (mText != null) {
                 out.writeInt(1);
                 mText.writeToParcel(out);
@@ -339,146 +457,141 @@
                 out.writeInt(0);
             }
         }
-    }
 
-    /**
-     * Provides access to information about a single view in the assist data.
-     */
-    static public class ViewNode {
-        /**
-         * Magic value for text color that has not been defined, which is very unlikely
-         * to be confused with a real text color.
-         */
-        public static final int TEXT_COLOR_UNDEFINED = 1;
+        public int getId() {
+            return mId;
+        }
 
-        public static final int TEXT_STYLE_BOLD = 1<<0;
-        public static final int TEXT_STYLE_ITALIC = 1<<1;
-        public static final int TEXT_STYLE_UNDERLINE = 1<<2;
-        public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
+        public String getIdPackage() {
+            return mIdPackage;
+        }
 
-        ViewNodeImpl mImpl;
+        public String getIdType() {
+            return mIdType;
+        }
 
-        public ViewNode() {
+        public String getIdEntry() {
+            return mIdEntry;
         }
 
         public int getLeft() {
-            return mImpl.mX;
+            return mX;
         }
 
         public int getTop() {
-            return mImpl.mY;
+            return mY;
         }
 
         public int getScrollX() {
-            return mImpl.mScrollX;
+            return mScrollX;
         }
 
         public int getScrollY() {
-            return mImpl.mScrollY;
+            return mScrollY;
         }
 
         public int getWidth() {
-            return mImpl.mWidth;
+            return mWidth;
         }
 
         public int getHeight() {
-            return mImpl.mHeight;
+            return mHeight;
         }
 
         public int getVisibility() {
-            return mImpl.mFlags&ViewNodeImpl.FLAGS_VISIBILITY_MASK;
+            return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
         }
 
         public boolean isEnabled() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_DISABLED) == 0;
+            return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
         }
 
         public boolean isClickable() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_CLICKABLE) != 0;
+            return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
         }
 
         public boolean isFocusable() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_FOCUSABLE) != 0;
+            return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
         }
 
         public boolean isFocused() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_FOCUSED) != 0;
+            return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
         }
 
         public boolean isAccessibilityFocused() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
+            return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
         }
 
         public boolean isCheckable() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_CHECKABLE) != 0;
+            return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
         }
 
         public boolean isChecked() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_CHECKED) != 0;
+            return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
         }
 
         public boolean isSelected() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_SELECTED) != 0;
+            return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
         }
 
         public boolean isActivated() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_ACTIVATED) != 0;
+            return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
         }
 
         public boolean isLongClickable() {
-            return (mImpl.mFlags&ViewNodeImpl.FLAGS_LONG_CLICKABLE) != 0;
+            return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
         }
 
         public String getClassName() {
-            return mImpl.mClassName;
+            return mClassName;
         }
 
-        public String getContentDescription() {
-            return mImpl.mContentDescription;
+        public CharSequence getContentDescription() {
+            return mContentDescription;
         }
 
         public CharSequence getText() {
-            return mImpl.mText != null ? mImpl.mText.mText : null;
+            return mText != null ? mText.mText : null;
         }
 
         public int getTextSelectionStart() {
-            return mImpl.mText != null ? mImpl.mText.mTextSelectionStart : -1;
+            return mText != null ? mText.mTextSelectionStart : -1;
         }
 
         public int getTextSelectionEnd() {
-            return mImpl.mText != null ? mImpl.mText.mTextSelectionEnd : -1;
+            return mText != null ? mText.mTextSelectionEnd : -1;
         }
 
         public int getTextColor() {
-            return mImpl.mText != null ? mImpl.mText.mTextColor : TEXT_COLOR_UNDEFINED;
+            return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
         }
 
         public int getTextBackgroundColor() {
-            return mImpl.mText != null ? mImpl.mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
+            return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
         }
 
         public float getTextSize() {
-            return mImpl.mText != null ? mImpl.mText.mTextSize : 0;
+            return mText != null ? mText.mTextSize : 0;
         }
 
         public int getTextStyle() {
-            return mImpl.mText != null ? mImpl.mText.mTextStyle : 0;
+            return mText != null ? mText.mTextStyle : 0;
         }
 
         public String getHint() {
-            return mImpl.mText != null ? mImpl.mText.mHint : null;
+            return mText != null ? mText.mHint : null;
         }
 
         public Bundle getExtras() {
-            return mImpl.mExtras;
+            return mExtras;
         }
 
         public int getChildCount() {
-            return mImpl.mChildren != null ? mImpl.mChildren.length : 0;
+            return mChildren != null ? mChildren.length : 0;
         }
 
-        public void getChildAt(int index, ViewNode outNode) {
-            outNode.mImpl = mImpl.mChildren[index];
+        public ViewNode getChildAt(int index) {
+            return mChildren[index];
         }
     }
 
@@ -488,12 +601,7 @@
                 activity.getActivityToken());
         for (int i=0; i<views.size(); i++) {
             ViewRootImpl root = views.get(i);
-            View view = root.getView();
-            Rect rect = new Rect();
-            view.getBoundsOnScreen(rect);
-            CharSequence title = root.getTitle();
-            mRootViews.add(new ViewNodeImpl(this, view, rect.left, rect.top,
-                    title != null ? title : view.getContentDescription()));
+            mWindowNodes.add(new WindowNode(this, root));
         }
     }
 
@@ -502,7 +610,7 @@
         mActivityComponent = ComponentName.readFromParcel(in);
         final int N = in.readInt();
         for (int i=0; i<N; i++) {
-            mRootViews.add(new ViewNodeImpl(in, preader));
+            mWindowNodes.add(new WindowNode(in, preader));
         }
         //dump();
     }
@@ -510,24 +618,37 @@
     /** @hide */
     public void dump() {
         Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
-        ViewNode node = new ViewNode();
-        final int N = getWindowCount();
+        final int N = getWindowNodeCount();
         for (int i=0; i<N; i++) {
-            Log.i(TAG, "Window #" + i + ":");
-            getWindowAt(i, node);
-            dump("  ", node);
+            WindowNode node = getWindowNodeAt(i);
+            Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop()
+                    + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle());
+            dump("  ", node.getRootViewNode());
         }
     }
 
     void dump(String prefix, ViewNode node) {
         Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
                 + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
+        int id = node.getId();
+        if (id != 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(prefix); sb.append("  ID: #"); sb.append(Integer.toHexString(id));
+            String entry = node.getIdEntry();
+            if (entry != null) {
+                String type = node.getIdType();
+                String pkg = node.getIdPackage();
+                sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type);
+                sb.append("/"); sb.append(entry);
+            }
+            Log.i(TAG, sb.toString());
+        }
         int scrollX = node.getScrollX();
         int scrollY = node.getScrollY();
         if (scrollX != 0 || scrollY != 0) {
             Log.i(TAG, prefix + "  Scroll: " + scrollX + "," + scrollY);
         }
-        String contentDescription = node.getContentDescription();
+        CharSequence contentDescription = node.getContentDescription();
         if (contentDescription != null) {
             Log.i(TAG, prefix + "  Content description: " + contentDescription);
         }
@@ -552,9 +673,8 @@
         if (NCHILDREN > 0) {
             Log.i(TAG, prefix + "  Children:");
             String cprefix = prefix + "    ";
-            ViewNode cnode = new ViewNode();
             for (int i=0; i<NCHILDREN; i++) {
-                node.getChildAt(i, cnode);
+                ViewNode cnode = node.getChildAt(i);
                 dump(cprefix, cnode);
             }
         }
@@ -575,17 +695,16 @@
     /**
      * Return the number of window contents that have been collected in this assist data.
      */
-    public int getWindowCount() {
-        return mRootViews.size();
+    public int getWindowNodeCount() {
+        return mWindowNodes.size();
     }
 
     /**
-     * Return the root view for one of the windows in the assist data.
-     * @param index Which window to retrieve, may be 0 to {@link #getWindowCount()}-1.
-     * @param outNode Node in which to place the window's root view.
+     * Return one of the windows in the assist data.
+     * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1.
      */
-    public void getWindowAt(int index, ViewNode outNode) {
-        outNode.mImpl = mRootViews.get(index);
+    public WindowNode getWindowNodeAt(int index) {
+        return mWindowNodes.get(index);
     }
 
     public int describeContents() {
@@ -596,10 +715,10 @@
         int start = out.dataPosition();
         PooledStringWriter pwriter = new PooledStringWriter(out);
         ComponentName.writeToParcel(mActivityComponent, out);
-        final int N = mRootViews.size();
+        final int N = mWindowNodes.size();
         out.writeInt(N);
         for (int i=0; i<N; i++) {
-            mRootViews.get(i).writeToParcel(out, pwriter);
+            mWindowNodes.get(i).writeToParcel(out, pwriter);
         }
         pwriter.finish();
         Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index eb27830..4ccd69f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1323,6 +1323,15 @@
                 Binder.getCallingUid());
     }
 
+    @Override
+    public int checkSelfPermission(String permission) {
+        if (permission == null) {
+            throw new IllegalArgumentException("permission is null");
+        }
+
+        return checkPermission(permission, Process.myPid(), Process.myUid());
+    }
+
     private void enforce(
             String permission, int resultOfCheck,
             boolean selfToo, int uid, String message) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index bdcc312..4fdae7f 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.animation.Animator;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.content.ComponentCallbacks2;
@@ -1092,13 +1093,7 @@
         if (mActivity == null) {
             throw new IllegalStateException("Fragment " + this + " not attached to Activity");
         }
-        if (options != null) {
-            mActivity.startActivityFromFragment(this, intent, requestCode, options);
-        } else {
-            // Note we want to go through this call for compatibility with
-            // applications that may have overridden the method.
-            mActivity.startActivityFromFragment(this, intent, requestCode, options);
-        }
+        mActivity.startActivityFromFragment(this, intent, requestCode, options);
     }
 
     /**
@@ -1119,6 +1114,98 @@
     }
 
     /**
+     * Requests permissions to be granted to this application. These permissions
+     * must be requested in your manifest, they should not be granted to your app,
+     * and they should have protection level {@link android.content.pm.PermissionInfo
+     * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by
+     * the platform or a third-party app.
+     * <p>
+     * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
+     * are granted at install time if requested in the manifest. Signature permissions
+     * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
+     * install time if requested in the manifest and the signature of your app matches
+     * the signature of the app declaring the permissions.
+     * </p>
+     * <p>
+     * If your app does not have the requested permissions the user will be presented
+     * with UI for accepting them. After the user has accepted or rejected the
+     * requested permissions you will receive a callback on {@link
+     * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
+     * permissions were granted or not.
+     * </p>
+     * <p>
+     * Note that requesting a permission does not guarantee it will be granted and
+     * your app should be able to run without having this permission.
+     * </p>
+     * <p>
+     * This method may start an activity allowing the user to choose which permissions
+     * to grant and which to reject. Hence, you should be prepared that your activity
+     * may be paused and resumed. Further, granting some permissions may require
+     * a restart of you application. In such a case, the system will recreate the
+     * activity stack before delivering the result to {@link
+     * #onRequestPermissionsResult(int, String[], int[])}.
+     * </p>
+     * <p>
+     * When checking whether you have a permission you should use {@link
+     * android.content.Context#checkSelfPermission(String)}.
+     * </p>
+     * <p>
+     * A sample permissions request looks like this:
+     * </p>
+     * <code><pre><p>
+     * private void showContacts() {
+     *     if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
+     *             != PackageManager.PERMISSION_GRANTED) {
+     *         requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+     *                 PERMISSIONS_REQUEST_READ_CONTACTS);
+     *     } else {
+     *         doShowContacts();
+     *     }
+     * }
+     *
+     * {@literal @}Override
+     * public void onRequestPermissionsResult(int requestCode, String[] permissions,
+     *         int[] grantResults) {
+     *     if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS
+     *             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+     *         doShowContacts();
+     *     }
+     * }
+     * </code></pre></p>
+     *
+     * @param permissions The requested permissions.
+     * @param requestCode Application specific request code to match with a result
+     *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
+     *
+     * @see #onRequestPermissionsResult(int, String[], int[])
+     * @see android.content.Context#checkSelfPermission(String)
+     */
+    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
+        if (mActivity == null) {
+            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+        }
+        Intent intent = mActivity.getPackageManager().buildRequestPermissionsIntent(permissions);
+        mActivity.startActivityFromFragment(this, intent, requestCode, null);
+    }
+
+    /**
+     * Callback for the result from requesting permissions. This method
+     * is invoked for every call on {@link #requestPermissions(String[], int)}.
+     *
+     * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
+     * @param permissions The requested permissions. Never null.
+     * @param grantResults The grant results for the corresponding permissions
+     *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
+     *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
+     *
+     * @see #requestPermissions(String[], int)
+     */
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+            @NonNull int[] grantResults) {
+        /* callback - do nothing */
+    }
+
+    /**
      * @hide Hack so that DialogFragment can make its Dialog before creating
      * its views, and the view construction can use the dialog's context for
      * inflation.  Maybe this should become a public API. Note sure.
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 5d864df..33262b3 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,6 +48,9 @@
     void setPackagePriority(String pkg, int uid, int priority);
     int getPackagePriority(String pkg, int uid);
 
+    void setPackagePeekable(String pkg, int uid, boolean peekable);
+    boolean getPackagePeekable(String pkg, int uid);
+
     void setPackageVisibilityOverride(String pkg, int uid, int visibility);
     int getPackageVisibilityOverride(String pkg, int uid);
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b824e97..b31ce04 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1840,6 +1840,26 @@
     }
 
     /**
+     * {@hide}
+     */
+    public static String priorityToString(@Priority int pri) {
+        switch (pri) {
+            case PRIORITY_MIN:
+                return "MIN";
+            case PRIORITY_LOW:
+                return "LOW";
+            case PRIORITY_DEFAULT:
+                return "DEFAULT";
+            case PRIORITY_HIGH:
+                return "HIGH";
+            case PRIORITY_MAX:
+                return "MAX";
+            default:
+                return "UNKNOWN(" + String.valueOf(pri) + ")";
+        }
+    }
+
+    /**
      * @hide
      */
     public boolean isValid() {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 682a468..6dde07b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -341,6 +341,18 @@
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
 
     /**
+     * An int extra holding a minimum required version code for the device admin package. If the
+     * device admin is already installed on the device, it will only be re-downloaded from
+     * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} if the version of the
+     * installed package is less than this version code.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE
+        = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE";
+
+    /**
      * A String extra holding a http cookie header which should be used in the http request to the
      * url specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
      *
@@ -411,6 +423,18 @@
         = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
 
     /**
+     * An int extra holding a minimum required version code for the device initializer package.
+     * If the initializer is already installed on the device, it will only be re-downloaded from
+     * {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION} if the version of
+     * the installed package is less than this version code.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE
+        = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
+
+    /**
      * A String extra holding a http cookie header which should be used in the http request to the
      * url specified in {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
      *
@@ -433,6 +457,50 @@
         = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
 
     /**
+     * A String extra holding the MAC address of the Bluetooth device to connect to with status
+     * updates during provisioning.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_BT_MAC_ADDRESS
+            = "android.app.extra.PROVISIONING_BT_MAC_ADDRESS";
+
+    /**
+     * A String extra holding the Bluetooth service UUID on the device to connect to with status
+     * updates during provisioning.
+     *
+     * <p>This value must be specified when {@code #EXTRA_PROVISIONING_BT_MAC_ADDRESS} is present.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_BT_UUID
+            = "android.app.extra.PROVISIONING_BT_UUID";
+
+    /**
+     * A String extra holding a unique identifier used to identify the device connecting over
+     * Bluetooth. This identifier will be part of every status message sent to the remote device.
+     *
+     * <p>This value must be specified when {@code #EXTRA_PROVISIONING_BT_MAC_ADDRESS} is present.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_BT_DEVICE_ID
+            = "android.app.extra.PROVISIONING_BT_DEVICE_ID";
+
+    /**
+     * A Boolean extra that that will cause a provisioned device to temporarily proxy network
+     * traffic over Bluetooth. When a Wi-Fi network is available, the network proxy will stop.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump.
+     */
+    public static final String EXTRA_PROVISIONING_BT_USE_PROXY
+            = "android.app.extra.PROVISIONING_BT_USE_PROXY";
+
+    /**
      * This MIME type is used for starting the Device Owner provisioning.
      *
      * <p>During device owner provisioning a device admin app is set as the owner of the device.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 80b5e0b..39a70be 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3109,6 +3109,20 @@
     public abstract int checkCallingOrSelfPermission(@NonNull String permission);
 
     /**
+     * Determine whether <em>you</em> have been granted a particular permission.
+     *
+     * @param permission The name of the permission being checked.
+     *
+     * @return {@link PackageManager#PERMISSION_GRANTED} if you have the
+     * permission, or {@link PackageManager#PERMISSION_DENIED} if not.
+     *
+     * @see PackageManager#checkPermission(String, String)
+     * @see #checkCallingPermission(String)
+     */
+    @PackageManager.PermissionResult
+    public abstract int checkSelfPermission(@NonNull String permission);
+
+    /**
      * If the given permission is not allowed for a particular process
      * and user ID running in the system, throw a {@link SecurityException}.
      *
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6e8b7c1..8c5a87c 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -602,6 +602,11 @@
     }
 
     @Override
+    public int checkSelfPermission(String permission) {
+       return mBase.checkSelfPermission(permission);
+    }
+
+    @Override
     public void enforcePermission(
             String permission, int pid, int uid, String message) {
         mBase.enforcePermission(permission, pid, uid, message);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f685475..9be96a1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1519,6 +1519,10 @@
      * </p><p>
      * See {@link android.os.PowerManager#isInteractive} for details.
      * </p>
+     * You <em>cannot</em> receive this through components declared in
+     * manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1539,6 +1543,10 @@
      * </p><p>
      * See {@link android.os.PowerManager#isInteractive} for details.
      * </p>
+     * You <em>cannot</em> receive this through components declared in
+     * manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1576,7 +1584,7 @@
 
     /**
      * Broadcast Action: The current time has changed.  Sent every
-     * minute.  You can <em>not</em> receive this through components declared
+     * minute.  You <em>cannot</em> receive this through components declared
      * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
      * Context.registerReceiver()}.
@@ -1922,7 +1930,7 @@
      * appropriately.
      *
      * <p class="note">
-     * You can <em>not</em> receive this through components declared
+     * You <em>cannot</em> receive this through components declared
      * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
      * Context.registerReceiver()}.
@@ -1949,7 +1957,7 @@
      * contents of the Intent.
      *
      * <p class="note">
-     * You can <em>not</em> receive this through components declared
+     * You <em>cannot</em> receive this through components declared
      * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
      * Context.registerReceiver()}.  See {@link #ACTION_BATTERY_LOW},
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 29befc8..8f17845 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -346,6 +346,11 @@
     public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27;
 
     /**
+     * When set installer extracts native libs from .apk files.
+     */
+    public static final int FLAG_EXTRACT_NATIVE_LIBS = 1<<28;
+
+    /**
      * Value for {@link #flags}: true if code from this application will need to be
      * loaded into other applications' processes. On devices that support multiple
      * instruction sets, this implies the code might be loaded into a process that's
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 3e5d362..c6d97f1 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -46,32 +46,34 @@
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.content.IntentSender;
+import com.android.internal.os.IResultReceiver;
 
 /**
  *  See {@link PackageManager} for documentation on most of the APIs
  *  here.
- * 
+ *
  *  {@hide}
  */
 interface IPackageManager {
     boolean isPackageAvailable(String packageName, int userId);
     PackageInfo getPackageInfo(String packageName, int flags, int userId);
     int getPackageUid(String packageName, int userId);
-    int[] getPackageGids(String packageName);
-    
+    int[] getPackageGids(String packageName, int userId);
+
     String[] currentToCanonicalPackageNames(in String[] names);
     String[] canonicalToCurrentPackageNames(in String[] names);
 
     PermissionInfo getPermissionInfo(String name, int flags);
-    
+
     List<PermissionInfo> queryPermissionsByGroup(String group, int flags);
-    
+
     PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
-    
+
     List<PermissionGroupInfo> getAllPermissionGroups(int flags);
-    
+
     ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId);
 
     ActivityInfo getActivityInfo(in ComponentName className, int flags, int userId);
@@ -85,28 +87,28 @@
 
     ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
 
-    int checkPermission(String permName, String pkgName);
-    
+    int checkPermission(String permName, String pkgName, int userId);
+
     int checkUidPermission(String permName, int uid);
-    
+
     boolean addPermission(in PermissionInfo info);
-    
+
     void removePermission(String name);
 
-    void grantPermission(String packageName, String permissionName);
+    boolean grantPermission(String packageName, String permissionName, int userId);
 
-    void revokePermission(String packageName, String permissionName);
+    boolean revokePermission(String packageName, String permissionName, int userId);
 
     boolean isProtectedBroadcast(String actionName);
-    
+
     int checkSignatures(String pkg1, String pkg2);
-    
+
     int checkUidSignatures(int uid1, int uid2);
-    
+
     String[] getPackagesForUid(int uid);
-    
+
     String getNameForUid(int uid);
-    
+
     int getUidForSharedUser(String sharedUserName);
 
     int getFlagsForUid(int uid);
@@ -121,7 +123,7 @@
 
     boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId);
 
-    List<ResolveInfo> queryIntentActivities(in Intent intent, 
+    List<ResolveInfo> queryIntentActivities(in Intent intent,
             String resolvedType, int flags, int userId);
 
     List<ResolveInfo> queryIntentActivityOptions(
@@ -168,7 +170,7 @@
 
     /**
      * Retrieve all applications that are marked as persistent.
-     * 
+     *
      * @return A List&lt;applicationInfo> containing one entry for each persistent
      *         application.
      */
@@ -178,7 +180,7 @@
 
     /**
      * Retrieve sync information for all content providers.
-     * 
+     *
      * @param outNames Filled in with a list of the root names of the content
      *                 providers that can sync.
      * @param outInfo Filled in with a list of the ProviderInfo for each
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 9223269..9e6c6b5 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -167,8 +167,7 @@
      * or null if there were none.  This is only filled in if the flag
      * {@link PackageManager#GET_PERMISSIONS} was set.  Each value matches
      * the corresponding entry in {@link #requestedPermissions}, and will have
-     * the flags {@link #REQUESTED_PERMISSION_REQUIRED} and
-     * {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
+     * the flag {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
      */
     public int[] requestedPermissionsFlags;
 
@@ -176,6 +175,8 @@
      * Flag for {@link #requestedPermissionsFlags}: the requested permission
      * is required for the application to run; the user can not optionally
      * disable it.  Currently all permissions are required.
+     *
+     * @removed We do not support required permissions.
      */
     public static final int REQUESTED_PERMISSION_REQUIRED = 1<<0;
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3da57cb..59a16da 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -44,6 +44,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.AndroidException;
+import com.android.internal.util.ArrayUtils;
 
 import java.io.File;
 import java.lang.annotation.Retention;
@@ -377,6 +378,16 @@
     public static final int INSTALL_ALLOW_DOWNGRADE = 0x00000080;
 
     /**
+     * Flag parameter for {@link #installPackage} to indicate that all runtime
+     * permissions should be granted to the package. If {@link #INSTALL_ALL_USERS}
+     * is set the runtime permissions will be granted to all users, otherwise
+     * only to the owner.
+     *
+     * @hide
+     */
+    public static final int INSTALL_GRANT_RUNTIME_PERMISSIONS = 0x00000100;
+
+    /**
      * Flag parameter for
      * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
      * that you don't want to kill the app containing the component.  Be careful when you set this
@@ -1663,21 +1674,46 @@
             = "android.content.pm.extra.VERIFICATION_VERSION_CODE";
 
     /**
-     * The action used to request that the user approve a permission request
-     * from the application.
+     * The action used to request that the user approve a grant permissions
+     * request from the application.
      *
      * @hide
      */
-    public static final String ACTION_REQUEST_PERMISSION
-            = "android.content.pm.action.REQUEST_PERMISSION";
+    @SystemApi
+    public static final String ACTION_REQUEST_PERMISSIONS =
+            "android.content.pm.action.REQUEST_PERMISSIONS";
 
     /**
-     * Extra field name for the list of permissions, which the user must approve.
+     * The component name handling runtime permission grants.
      *
      * @hide
      */
-    public static final String EXTRA_REQUEST_PERMISSION_PERMISSION_LIST
-            = "android.content.pm.extra.PERMISSION_LIST";
+    public static final String GRANT_PERMISSIONS_PACKAGE_NAME =
+            "com.android.packageinstaller";
+
+    /**
+     * The names of the requested permissions.
+     * <p>
+     * <strong>Type:</strong> String[]
+     * </p>
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_REQUEST_PERMISSIONS_NAMES =
+            "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
+
+    /**
+     * The results from the permissions request.
+     * <p>
+     * <strong>Type:</strong> int[] of #PermissionResult
+     * </p>
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS
+            = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
 
     /**
      * String extra for {@link PackageInstallObserver} in the 'extras' Bundle in case of
@@ -2184,53 +2220,72 @@
     public abstract void removePermission(String name);
 
     /**
-     * Returns an {@link Intent} suitable for passing to {@code startActivityForResult}
-     * which prompts the user to grant {@code permissions} to this application.
-     * @hide
+     * Grant a runtime permission to an application which the application does not
+     * already have. The permission must have been requested by the application.
+     * If the application is not allowed to hold the permission, a {@link
+     * java.lang.SecurityException} is thrown.
+     * <p>
+     * <strong>Note: </strong>Using this API requires holding
+     * android.permission.GRANT_REVOKE_PERMISSIONS and if the user id is
+     * not the current user android.permission.INTERACT_ACROSS_USERS_FULL.
+     * </p>
      *
-     * @throws NullPointerException if {@code permissions} is {@code null}.
-     * @throws IllegalArgumentException if {@code permissions} contains {@code null}.
+     * @param packageName The package to which to grant the permission.
+     * @param permissionName The permission name to grant.
+     * @param user The user for which to grant the permission.
+     *
+     * @see #revokePermission(String, String, android.os.UserHandle)
+     *
+     * @hide
      */
-    public Intent buildPermissionRequestIntent(String... permissions) {
-        if (permissions == null) {
-            throw new NullPointerException("permissions cannot be null");
-        }
-        for (String permission : permissions) {
-            if (permission == null) {
-                throw new IllegalArgumentException("permissions cannot contain null");
-            }
-        }
+    @SystemApi
+    public abstract void grantPermission(@NonNull String packageName,
+            @NonNull String permissionName, @NonNull UserHandle user);
 
-        Intent i = new Intent(ACTION_REQUEST_PERMISSION);
-        i.putExtra(EXTRA_REQUEST_PERMISSION_PERMISSION_LIST, permissions);
-        i.setPackage("com.android.packageinstaller");
-        return i;
+    /**
+     * Revoke a runtime permission that was previously granted by {@link
+     * #grantPermission(String, String, android.os.UserHandle)}. The permission
+     * must have been requested by and granted to the application. If the
+     * application is not allowed to hold the permission, a {@link
+     * java.lang.SecurityException} is thrown.
+     * <p>
+     * <strong>Note: </strong>Using this API requires holding
+     * android.permission.GRANT_REVOKE_PERMISSIONS and if the user id is
+     * not the current user android.permission.INTERACT_ACROSS_USERS_FULL.
+     * </p>
+     *
+     * @param packageName The package from which to revoke the permission.
+     * @param permissionName The permission name to revoke.
+     * @param user The user for which to revoke the permission.
+     *
+     * @see #grantPermission(String, String, android.os.UserHandle)
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract void revokePermission(@NonNull String packageName,
+            @NonNull String permissionName, @NonNull UserHandle user);
+
+    /**
+     * Returns an {@link android.content.Intent} suitable for passing to
+     * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
+     * which prompts the user to grant permissions to this application.
+     *
+     * @throws NullPointerException if {@code permissions} is {@code null} or empty.
+     *
+     * @hide
+     */
+    public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
+        if (ArrayUtils.isEmpty(permissions)) {
+           throw new NullPointerException("permission cannot be null or empty");
+        }
+        Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
+        intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);
+        intent.setPackage(GRANT_PERMISSIONS_PACKAGE_NAME);
+        return intent;
     }
 
     /**
-     * Grant a permission to an application which the application does not
-     * already have.  The permission must have been requested by the application,
-     * but as an optional permission.  If the application is not allowed to
-     * hold the permission, a SecurityException is thrown.
-     * @hide
-     *
-     * @param packageName The name of the package that the permission will be
-     * granted to.
-     * @param permissionName The name of the permission.
-     */
-    public abstract void grantPermission(String packageName, String permissionName);
-
-    /**
-     * Revoke a permission that was previously granted by {@link #grantPermission}.
-     * @hide
-     *
-     * @param packageName The name of the package that the permission will be
-     * granted to.
-     * @param permissionName The name of the permission.
-     */
-    public abstract void revokePermission(String packageName, String permissionName);
-
-    /**
      * Compare the signatures of two packages to determine if the same
      * signature appears in both of them.  If they do contain the same
      * signature, then they are allowed special privileges when working
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c443ff3..e5859d03 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -269,6 +269,7 @@
 
         public final boolean coreApp;
         public final boolean multiArch;
+        public final boolean extractNativeLibs;
 
         public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
                 String[] splitCodePaths, int[] splitRevisionCodes) {
@@ -284,6 +285,7 @@
             this.splitRevisionCodes = splitRevisionCodes;
             this.coreApp = baseApk.coreApp;
             this.multiArch = baseApk.multiArch;
+            this.extractNativeLibs = baseApk.extractNativeLibs;
         }
 
         public List<String> getAllCodePaths() {
@@ -310,10 +312,12 @@
         public final Signature[] signatures;
         public final boolean coreApp;
         public final boolean multiArch;
+        public final boolean extractNativeLibs;
 
         public ApkLite(String codePath, String packageName, String splitName, int versionCode,
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
-                Signature[] signatures, boolean coreApp, boolean multiArch) {
+                Signature[] signatures, boolean coreApp, boolean multiArch,
+                boolean extractNativeLibs) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -324,6 +328,7 @@
             this.signatures = signatures;
             this.coreApp = coreApp;
             this.multiArch = multiArch;
+            this.extractNativeLibs = extractNativeLibs;
         }
     }
 
@@ -410,7 +415,7 @@
 
     public static PackageInfo generatePackageInfo(PackageParser.Package p,
             int gids[], int flags, long firstInstallTime, long lastUpdateTime,
-            ArraySet<String> grantedPermissions, PackageUserState state, int userId) {
+            Set<String> grantedPermissions, PackageUserState state, int userId) {
 
         if (!checkUseInstalledOrHidden(flags, state)) {
             return null;
@@ -569,9 +574,8 @@
                 for (int i=0; i<N; i++) {
                     final String perm = p.requestedPermissions.get(i);
                     pi.requestedPermissions[i] = perm;
-                    if (p.requestedPermissionsRequired.get(i)) {
-                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
-                    }
+                    // The notion of requried permissions is deprecated but for compatibility.
+                    pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
                     if (grantedPermissions != null && grantedPermissions.contains(perm)) {
                         pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
                     }
@@ -1270,6 +1274,7 @@
         int revisionCode = 0;
         boolean coreApp = false;
         boolean multiArch = false;
+        boolean extractNativeLibs = true;
 
         for (int i = 0; i < attrs.getAttributeCount(); i++) {
             final String attr = attrs.getAttributeName(i);
@@ -1308,14 +1313,17 @@
                     final String attr = attrs.getAttributeName(i);
                     if ("multiArch".equals(attr)) {
                         multiArch = attrs.getAttributeBooleanValue(i, false);
-                        break;
+                    }
+                    if ("extractNativeLibs".equals(attr)) {
+                        extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
                     }
                 }
             }
         }
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
-                revisionCode, installLocation, verifiers, signatures, coreApp, multiArch);
+                revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
+                extractNativeLibs);
     }
 
     /**
@@ -1812,7 +1820,6 @@
                 }
                 implicitPerms.append(npi.name);
                 pkg.requestedPermissions.add(npi.name);
-                pkg.requestedPermissionsRequired.add(Boolean.TRUE);
             }
         }
         if (implicitPerms != null) {
@@ -1831,7 +1838,6 @@
                 final String perm = spi.newPerms[in];
                 if (!pkg.requestedPermissions.contains(perm)) {
                     pkg.requestedPermissions.add(perm);
-                    pkg.requestedPermissionsRequired.add(Boolean.TRUE);
                 }
             }
         }
@@ -1865,17 +1871,6 @@
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
         }
 
-        /*
-         * b/8528162: Ignore the <uses-permission android:required> attribute if
-         * targetSdkVersion < JELLY_BEAN_MR2. There are lots of apps in the wild
-         * which are improperly using this attribute, even though it never worked.
-         */
-        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) {
-            for (int i = 0; i < pkg.requestedPermissionsRequired.size(); i++) {
-                pkg.requestedPermissionsRequired.set(i, Boolean.TRUE);
-            }
-        }
-
         return pkg;
     }
 
@@ -1911,11 +1906,6 @@
         // that may change.
         String name = sa.getNonResourceString(
                 com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
-/*
-        boolean required = sa.getBoolean(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_required, true);
-*/
-        boolean required = true; // Optional <uses-permission> not supported
 
         int maxSdkVersion = 0;
         TypedValue val = sa.peekValue(
@@ -1933,13 +1923,9 @@
                 int index = pkg.requestedPermissions.indexOf(name);
                 if (index == -1) {
                     pkg.requestedPermissions.add(name.intern());
-                    pkg.requestedPermissionsRequired.add(required ? Boolean.TRUE : Boolean.FALSE);
                 } else {
-                    if (pkg.requestedPermissionsRequired.get(index) != required) {
-                        outError[0] = "conflicting <uses-permission> entries";
-                        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-                        return false;
-                    }
+                    Slog.w(TAG, "Ignoring duplicate uses-permission: " + name + " in package: "
+                            + pkg.packageName + " at: " + parser.getPositionDescription());
                 }
             }
         }
@@ -2569,6 +2555,12 @@
             ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
         }
 
+        if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
+                true)) {
+            ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
+        }
+
         String str;
         str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
@@ -3116,8 +3108,7 @@
             }
 
             a.info.resizeable = sa.getBoolean(
-                    R.styleable.AndroidManifestActivity_resizeableActivity,
-                    owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.MNC);
+                    R.styleable.AndroidManifestActivity_resizeableActivity, false);
             if (a.info.resizeable) {
                 // Fixed screen orientation isn't supported with resizeable activities.
                 a.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -4218,7 +4209,6 @@
         public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
 
         public final ArrayList<String> requestedPermissions = new ArrayList<String>();
-        public final ArrayList<Boolean> requestedPermissionsRequired = new ArrayList<Boolean>();
 
         public ArrayList<String> protectedBroadcasts;
 
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 841b09d..7d8dff3 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -464,6 +464,33 @@
         return mColors;
     }
 
+    /**
+     * Returns whether the specified state is referenced in any of the state
+     * specs contained within this ColorStateList.
+     * <p>
+     * Any reference, either positive or negative {ex. ~R.attr.state_enabled},
+     * will cause this method to return {@code true}. Wildcards are not counted
+     * as references.
+     *
+     * @param state the state to search for
+     * @return {@code true} if the state if referenced, {@code false} otherwise
+     * @hide Use only as directed. For internal use only.
+     */
+    public boolean hasState(int state) {
+        final int[][] stateSpecs = mStateSpecs;
+        final int specCount = stateSpecs.length;
+        for (int specIndex = 0; specIndex < specCount; specIndex++) {
+            final int[] states = stateSpecs[specIndex];
+            final int stateCount = states.length;
+            for (int stateIndex = 0; stateIndex < stateCount; stateIndex++) {
+                if (states[stateIndex] == state || states[stateIndex] == ~state) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     public String toString() {
         return "ColorStateList{" +
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 9aede01..d5dfaf6 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -18,8 +18,6 @@
 
 import android.hardware.ICamera;
 import android.hardware.ICameraClient;
-import android.hardware.IProCameraUser;
-import android.hardware.IProCameraCallbacks;
 import android.hardware.camera2.ICameraDeviceUser;
 import android.hardware.camera2.ICameraDeviceCallbacks;
 import android.hardware.camera2.impl.CameraMetadataNative;
@@ -45,12 +43,6 @@
                     // Container for an ICamera object
                     out BinderHolder device);
 
-    int connectPro(IProCameraCallbacks callbacks, int cameraId,
-                              String clientPackageName,
-                              int clientUid,
-                              // Container for an IProCameraUser object
-                              out BinderHolder device);
-
     int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
                               String clientPackageName,
                               int clientUid,
diff --git a/core/java/android/hardware/IProCameraCallbacks.aidl b/core/java/android/hardware/IProCameraCallbacks.aidl
deleted file mode 100644
index a09b452..0000000
--- a/core/java/android/hardware/IProCameraCallbacks.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/** @hide */
-interface IProCameraCallbacks
-{
-    /**
-     * Keep up-to-date with frameworks/av/include/camera/IProCameraCallbacks.h
-     */
-    // TODO: consider implementing this.
-}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 116110e..6209c2a 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -888,6 +888,21 @@
                 }
                 return;
             }
+
+            @Override
+            public void waitForAsecScan() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_waitForAsecScan, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return;
+            }
         }
 
         private static final String DESCRIPTOR = "IMountService";
@@ -978,6 +993,8 @@
 
         static final int TRANSACTION_runMaintenance = IBinder.FIRST_CALL_TRANSACTION + 42;
 
+        static final int TRANSACTION_waitForAsecScan = IBinder.FIRST_CALL_TRANSACTION + 43;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1396,6 +1413,12 @@
                     reply.writeNoException();
                     return true;
                 }
+                case TRANSACTION_waitForAsecScan: {
+                    data.enforceInterface(DESCRIPTOR);
+                    waitForAsecScan();
+                    reply.writeNoException();
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1680,4 +1703,6 @@
      * @throws RemoteException
      */
     public void runMaintenance() throws RemoteException;
+
+    public void waitForAsecScan() throws RemoteException;
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 06862d7..74b0a1c 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1516,8 +1516,14 @@
         /**
          * Build a {@link #CONTENT_LOOKUP_URI} lookup {@link Uri} using the
          * given {@link ContactsContract.Contacts#_ID} and {@link #LOOKUP_KEY}.
+         * <p>
+         * Returns null if unable to construct a valid lookup URI from the
+         * provided parameters.
          */
         public static Uri getLookupUri(long contactId, String lookupKey) {
+            if (TextUtils.isEmpty(lookupKey)) {
+                return null;
+            }
             return ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
                     lookupKey), contactId);
         }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e6b39b5..de536bd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5375,6 +5375,7 @@
             BACKUP_AUTO_RESTORE,
             ENABLED_ACCESSIBILITY_SERVICES,
             ENABLED_NOTIFICATION_LISTENERS,
+            ENABLED_INPUT_METHODS,
             TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
             TOUCH_EXPLORATION_ENABLED,
             ACCESSIBILITY_ENABLED,
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
new file mode 100644
index 0000000..c7274e8
--- /dev/null
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2015, 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.security;
+
+/**
+ * Network security policy.
+ *
+ * @hide
+ */
+public class NetworkSecurityPolicy {
+
+  private static final NetworkSecurityPolicy INSTANCE = new NetworkSecurityPolicy();
+
+  private boolean mCleartextTrafficPermitted = true;
+
+  private NetworkSecurityPolicy() {}
+
+  /**
+   * Gets the policy.
+   */
+  public static NetworkSecurityPolicy getInstance() {
+    return INSTANCE;
+  }
+
+  /**
+   * Checks whether cleartext network traffic (e.g., HTTP, WebSockets, XMPP, IMAP, SMTP -- without
+   * TLS or STARTTLS) is permitted for this process.
+   *
+   * <p>When cleartext network traffic is not permitted, the platform's components (e.g., HTTP
+   * stacks, {@code WebView}, {@code MediaPlayer}) will refuse this process's requests to use
+   * cleartext traffic. Third-party libraries are encouraged to honor this setting as well.
+   */
+  public boolean isCleartextTrafficPermitted() {
+    synchronized (this) {
+      return mCleartextTrafficPermitted;
+    }
+  }
+
+  /**
+   * Sets whether cleartext network traffic is permitted for this process.
+   *
+   * <p>This method is used by the platform early on in the application's initialization to set the
+   * policy.
+   *
+   * @hide
+   */
+  public void setCleartextTrafficPermitted(boolean permitted) {
+    synchronized (this) {
+      mCleartextTrafficPermitted = permitted;
+    }
+  }
+}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 4902a71..d46b6f5 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -17,15 +17,12 @@
 package android.service.wallpaper;
 
 import android.content.res.TypedArray;
-import android.os.Build;
 import android.os.SystemProperties;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.ViewRootImpl;
 import android.view.WindowInsets;
 
 import com.android.internal.R;
 import com.android.internal.os.HandlerCaller;
+import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.BaseSurfaceHolder;
 
@@ -158,7 +155,7 @@
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
         int mCurWindowFlags = mWindowFlags;
         int mCurWindowPrivateFlags = mWindowPrivateFlags;
-        TypedValue mOutsetBottom;
+        int mOutsetBottomPx;
         final Rect mVisibleInsets = new Rect();
         final Rect mWinFrame = new Rect();
         final Rect mOverscanInsets = new Rect();
@@ -171,8 +168,6 @@
         final Rect mFinalStableInsets = new Rect();
         final Configuration mConfiguration = new Configuration();
 
-        private boolean mIsEmulator;
-        private boolean mIsCircularEmulator;
         private boolean mWindowIsRound;
 
         final WindowManager.LayoutParams mLayout
@@ -637,23 +632,13 @@
                         final Display display = windowService.getDefaultDisplay();
                         final boolean shouldUseBottomOutset =
                                 display.getDisplayId() == Display.DEFAULT_DISPLAY;
-                        if (shouldUseBottomOutset && windowStyle.hasValue(
-                                R.styleable.Window_windowOutsetBottom)) {
-                            if (mOutsetBottom == null) mOutsetBottom = new TypedValue();
-                            windowStyle.getValue(R.styleable.Window_windowOutsetBottom,
-                                    mOutsetBottom);
-                        } else {
-                            mOutsetBottom = null;
+                        if (shouldUseBottomOutset) {
+                            mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
+                                    getResources().getDisplayMetrics(), windowStyle);
                         }
-                        mWindowIsRound = getResources().getBoolean(
-                                com.android.internal.R.bool.config_windowIsRound);
+                        mWindowIsRound = ScreenShapeHelper.getWindowIsRound(getResources());
                         windowStyle.recycle();
 
-                        // detect emulator
-                        mIsEmulator = Build.HARDWARE.contains("goldfish");
-                        mIsCircularEmulator = SystemProperties.getBoolean(
-                                ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false);
-
                         // Add window
                         mLayout.type = mIWallpaperEngine.mWindowType;
                         mLayout.gravity = Gravity.START|Gravity.TOP;
@@ -783,18 +768,14 @@
                             mDispatchedOverscanInsets.set(mOverscanInsets);
                             mDispatchedContentInsets.set(mContentInsets);
                             mDispatchedStableInsets.set(mStableInsets);
-                            final boolean isRound = (mIsEmulator && mIsCircularEmulator)
-                                    || mWindowIsRound;
                             mFinalSystemInsets.set(mDispatchedOverscanInsets);
                             mFinalStableInsets.set(mDispatchedStableInsets);
-                            if (mOutsetBottom != null) {
-                                final DisplayMetrics metrics = getResources().getDisplayMetrics();
+                            if (mOutsetBottomPx != 0) {
                                 mFinalSystemInsets.bottom =
-                                        ( (int) mOutsetBottom.getDimension(metrics) )
-                                        + mIWallpaperEngine.mDisplayPadding.bottom;
+                                        mIWallpaperEngine.mDisplayPadding.bottom + mOutsetBottomPx;
                             }
                             WindowInsets insets = new WindowInsets(mFinalSystemInsets,
-                                    null, mFinalStableInsets, isRound);
+                                    null, mFinalStableInsets, mWindowIsRound);
                             onApplyWindowInsets(insets);
                         }
 
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 358ae8a..2eac549 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -49,6 +49,7 @@
     private final String mName;
     private final int mVendorId;
     private final int mProductId;
+    private final String mUniqueId;
     private final String mDescriptor;
     private final InputDeviceIdentifier mIdentifier;
     private final boolean mIsExternal;
@@ -356,14 +357,16 @@
 
     // Called by native code.
     private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
-            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
-            KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasButtonUnderPad) {
+            int productId, String uniqueId, String descriptor, boolean isExternal, int sources,
+            int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator,
+            boolean hasButtonUnderPad) {
         mId = id;
         mGeneration = generation;
         mControllerNumber = controllerNumber;
         mName = name;
         mVendorId = vendorId;
         mProductId = productId;
+        mUniqueId = uniqueId;
         mDescriptor = descriptor;
         mIsExternal = isExternal;
         mSources = sources;
@@ -381,6 +384,7 @@
         mName = in.readString();
         mVendorId = in.readInt();
         mProductId = in.readInt();
+        mUniqueId = in.readString();
         mDescriptor = in.readString();
         mIsExternal = in.readInt() != 0;
         mSources = in.readInt();
@@ -505,6 +509,23 @@
     }
 
     /**
+     * Gets the vendor's unique id for the given device, if available.
+     * <p>
+     * A vendor may assign a unique id to a device (e.g., MAC address for
+     * Bluetooth devices). A null value will be assigned where a unique id is
+     * not available.
+     * </p><p>
+     * This method is dependent on the vendor, whereas {@link #getDescriptor}
+     * attempts to create a unique id even when the vendor has not provided one.
+     * </p>
+     *
+     * @return The unique id of a given device
+     */
+    public String getUniqueId() {
+        return mUniqueId;
+    }
+
+    /**
      * Gets the input device descriptor, which is a stable identifier for an input device.
      * <p>
      * An input device descriptor uniquely identifies an input device.  Its value
@@ -843,6 +864,7 @@
         out.writeString(mName);
         out.writeInt(mVendorId);
         out.writeInt(mProductId);
+        out.writeString(mUniqueId);
         out.writeString(mDescriptor);
         out.writeInt(mIsExternal ? 1 : 0);
         out.writeInt(mSources);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 1a07aee..457d6ad 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -452,9 +452,10 @@
         synchronized (mConstructorArgs) {
             Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");
 
+            final Context inflaterContext = mContext;
             final AttributeSet attrs = Xml.asAttributeSet(parser);
-            Context lastContext = (Context)mConstructorArgs[0];
-            mConstructorArgs[0] = mContext;
+            Context lastContext = (Context) mConstructorArgs[0];
+            mConstructorArgs[0] = inflaterContext;
             View result = root;
 
             try {
@@ -485,10 +486,10 @@
                                 + "ViewGroup root and attachToRoot=true");
                     }
 
-                    rInflate(parser, root, attrs, false, false);
+                    rInflate(parser, root, inflaterContext, attrs, false);
                 } else {
                     // Temp is the root view that was found in the xml
-                    final View temp = createViewFromTag(root, name, attrs, false);
+                    final View temp = createViewFromTag(root, name, inflaterContext, attrs);
 
                     ViewGroup.LayoutParams params = null;
 
@@ -509,8 +510,10 @@
                     if (DEBUG) {
                         System.out.println("-----> start inflating children");
                     }
-                    // Inflate all children under temp
-                    rInflate(parser, temp, attrs, true, true);
+
+                    // Inflate all children under temp against its context.
+                    rInflateChildren(parser, temp, attrs, true);
+
                     if (DEBUG) {
                         System.out.println("-----> done inflating children");
                     }
@@ -692,59 +695,68 @@
     }
 
     /**
+     * Convenience method for calling through to the five-arg createViewFromTag
+     * method. This method passes {@code false} for the {@code ignoreThemeAttr}
+     * argument and should be used for everything except {@code &gt;include>}
+     * tag parsing.
+     */
+    private View createViewFromTag(View parent, String name, Context context, AttributeSet attrs) {
+        return createViewFromTag(parent, name, context, attrs, false);
+    }
+
+    /**
      * Creates a view from a tag name using the supplied attribute set.
      * <p>
-     * If {@code inheritContext} is true and the parent is non-null, the view
-     * will be inflated in parent view's context. If the view specifies a
-     * &lt;theme&gt; attribute, the inflation context will be wrapped with the
-     * specified theme.
-     * <p>
-     * Note: Default visibility so the BridgeInflater can override it.
+     * <strong>Note:</strong> Default visibility so the BridgeInflater can
+     * override it.
+     *
+     * @param parent the parent view, used to inflate layout params
+     * @param name the name of the XML tag used to define the view
+     * @param context the inflation context for the view, typically the
+     *                {@code parent} or base layout inflater context
+     * @param attrs the attribute set for the XML tag used to define the view
+     * @param ignoreThemeAttr {@code true} to ignore the {@code android:theme}
+     *                        attribute (if set) for the view being inflated,
+     *                        {@code false} otherwise
      */
-    View createViewFromTag(View parent, String name, AttributeSet attrs, boolean inheritContext) {
+    View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
+            boolean ignoreThemeAttr) {
         if (name.equals("view")) {
             name = attrs.getAttributeValue(null, "class");
         }
 
-        Context viewContext;
-        if (parent != null && inheritContext) {
-            viewContext = parent.getContext();
-        } else {
-            viewContext = mContext;
+        // Apply a theme wrapper, if allowed and one is specified.
+        if (!ignoreThemeAttr) {
+            final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
+            final int themeResId = ta.getResourceId(0, 0);
+            if (themeResId != 0) {
+                context = new ContextThemeWrapper(context, themeResId);
+            }
+            ta.recycle();
         }
 
-        // Apply a theme wrapper, if requested.
-        final TypedArray ta = viewContext.obtainStyledAttributes(attrs, ATTRS_THEME);
-        final int themeResId = ta.getResourceId(0, 0);
-        if (themeResId != 0) {
-            viewContext = new ContextThemeWrapper(viewContext, themeResId);
-        }
-        ta.recycle();
-
         if (name.equals(TAG_1995)) {
             // Let's party like it's 1995!
-            return new BlinkLayout(viewContext, attrs);
+            return new BlinkLayout(context, attrs);
         }
 
-        if (DEBUG) System.out.println("******** Creating view: " + name);
-
         try {
             View view;
             if (mFactory2 != null) {
-                view = mFactory2.onCreateView(parent, name, viewContext, attrs);
+                view = mFactory2.onCreateView(parent, name, context, attrs);
             } else if (mFactory != null) {
-                view = mFactory.onCreateView(name, viewContext, attrs);
+                view = mFactory.onCreateView(name, context, attrs);
             } else {
                 view = null;
             }
 
             if (view == null && mPrivateFactory != null) {
-                view = mPrivateFactory.onCreateView(parent, name, viewContext, attrs);
+                view = mPrivateFactory.onCreateView(parent, name, context, attrs);
             }
 
             if (view == null) {
                 final Object lastContext = mConstructorArgs[0];
-                mConstructorArgs[0] = viewContext;
+                mConstructorArgs[0] = context;
                 try {
                     if (-1 == name.indexOf('.')) {
                         view = onCreateView(parent, name, attrs);
@@ -756,20 +768,18 @@
                 }
             }
 
-            if (DEBUG) System.out.println("Created view is: " + view);
             return view;
-
         } catch (InflateException e) {
             throw e;
 
         } catch (ClassNotFoundException e) {
-            InflateException ie = new InflateException(attrs.getPositionDescription()
+            final InflateException ie = new InflateException(attrs.getPositionDescription()
                     + ": Error inflating class " + name);
             ie.initCause(e);
             throw ie;
 
         } catch (Exception e) {
-            InflateException ie = new InflateException(attrs.getPositionDescription()
+            final InflateException ie = new InflateException(attrs.getPositionDescription()
                     + ": Error inflating class " + name);
             ie.initCause(e);
             throw ie;
@@ -777,16 +787,26 @@
     }
 
     /**
+     * Recursive method used to inflate internal (non-root) children. This
+     * method calls through to {@link #rInflate} using the parent context as
+     * the inflation context.
+     * <strong>Note:</strong> Default visibility so the BridgeInflater can
+     * call it.
+     */
+    final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs,
+            boolean finishInflate) throws XmlPullParserException, IOException {
+        rInflate(parser, parent, parent.getContext(), attrs, finishInflate);
+    }
+
+    /**
      * Recursive method used to descend down the xml hierarchy and instantiate
      * views, instantiate their children, and then call onFinishInflate().
-     *
-     * @param inheritContext Whether the root view should be inflated in its
-     *            parent's context. This should be true when called inflating
-     *            child views recursively, or false otherwise.
+     * <p>
+     * <strong>Note:</strong> Default visibility so the BridgeInflater can
+     * override it.
      */
-    void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
-            boolean finishInflate, boolean inheritContext) throws XmlPullParserException,
-            IOException {
+    void rInflate(XmlPullParser parser, View parent, Context context,
+            AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
 
         final int depth = parser.getDepth();
         int type;
@@ -808,19 +828,21 @@
                 if (parser.getDepth() == 0) {
                     throw new InflateException("<include /> cannot be the root element");
                 }
-                parseInclude(parser, parent, attrs, inheritContext);
+                parseInclude(parser, context, parent, attrs);
             } else if (TAG_MERGE.equals(name)) {
                 throw new InflateException("<merge /> must be the root element");
             } else {
-                final View view = createViewFromTag(parent, name, attrs, inheritContext);
+                final View view = createViewFromTag(parent, name, context, attrs);
                 final ViewGroup viewGroup = (ViewGroup) parent;
                 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
-                rInflate(parser, view, attrs, true, true);
+                rInflateChildren(parser, view, attrs, true);
                 viewGroup.addView(view, params);
             }
         }
 
-        if (finishInflate) parent.onFinishInflate();
+        if (finishInflate) {
+            parent.onFinishInflate();
+        }
     }
 
     /**
@@ -829,13 +851,9 @@
      */
     private void parseRequestFocus(XmlPullParser parser, View view)
             throws XmlPullParserException, IOException {
-        int type;
         view.requestFocus();
-        final int currentDepth = parser.getDepth();
-        while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
-            // Empty
-        }
+
+        consumeChildElements(parser);
     }
 
     /**
@@ -844,33 +862,29 @@
      */
     private void parseViewTag(XmlPullParser parser, View view, AttributeSet attrs)
             throws XmlPullParserException, IOException {
-        int type;
-
-        final TypedArray ta = view.getContext().obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.ViewTag);
-        final int key = ta.getResourceId(com.android.internal.R.styleable.ViewTag_id, 0);
-        final CharSequence value = ta.getText(com.android.internal.R.styleable.ViewTag_value);
+        final Context context = view.getContext();
+        final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ViewTag);
+        final int key = ta.getResourceId(R.styleable.ViewTag_id, 0);
+        final CharSequence value = ta.getText(R.styleable.ViewTag_value);
         view.setTag(key, value);
         ta.recycle();
 
-        final int currentDepth = parser.getDepth();
-        while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
-            // Empty
-        }
+        consumeChildElements(parser);
     }
 
-    private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs,
-            boolean inheritContext) throws XmlPullParserException, IOException {
+    private void parseInclude(XmlPullParser parser, Context context, View parent,
+            AttributeSet attrs) throws XmlPullParserException, IOException {
         int type;
 
         if (parent instanceof ViewGroup) {
-            Context context = inheritContext ? parent.getContext() : mContext;
-
-            // Apply a theme wrapper, if requested.
+            // Apply a theme wrapper, if requested. This is sort of a weird
+            // edge case, since developers think the <include> overwrites
+            // values in the AttributeSet of the included View. So, if the
+            // included View has a theme attribute, we'll need to ignore it.
             final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
             final int themeResId = ta.getResourceId(0, 0);
-            if (themeResId != 0) {
+            final boolean hasThemeOverride = themeResId != 0;
+            if (hasThemeOverride) {
                 context = new ContextThemeWrapper(context, themeResId);
             }
             ta.recycle();
@@ -880,11 +894,12 @@
             int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
             if (layout == 0) {
                 final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null || value.length() < 1) {
+                if (value == null || value.length() <= 0) {
                     throw new InflateException("You must specify a layout in the"
                             + " include tag: <include layout=\"@layout/layoutID\" />");
                 }
 
+                // Attempt to resolve the "?attr/name" string to an identifier.
                 layout = context.getResources().getIdentifier(value.substring(1), null, null);
             }
 
@@ -901,8 +916,7 @@
                 throw new InflateException("You must specify a valid layout "
                         + "reference. The layout ID " + value + " is not valid.");
             } else {
-                final XmlResourceParser childParser =
-                        getContext().getResources().getLayout(layout);
+                final XmlResourceParser childParser = context.getResources().getLayout(layout);
 
                 try {
                     final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
@@ -920,11 +934,12 @@
                     final String childName = childParser.getName();
 
                     if (TAG_MERGE.equals(childName)) {
-                        // Inflate all children.
-                        rInflate(childParser, parent, childAttrs, false, inheritContext);
+                        // The <merge> tag doesn't support android:theme, so
+                        // nothing special to do here.
+                        rInflate(childParser, parent, context, childAttrs, false);
                     } else {
-                        final View view = createViewFromTag(parent, childName, childAttrs,
-                                inheritContext);
+                        final View view = createViewFromTag(parent, childName,
+                                context, childAttrs, hasThemeOverride);
                         final ViewGroup group = (ViewGroup) parent;
 
                         final TypedArray a = context.obtainStyledAttributes(
@@ -957,7 +972,7 @@
                         view.setLayoutParams(params);
 
                         // Inflate all children.
-                        rInflate(childParser, view, childAttrs, true, true);
+                        rInflateChildren(childParser, view, childAttrs, true);
 
                         if (id != View.NO_ID) {
                             view.setId(id);
@@ -985,6 +1000,16 @@
             throw new InflateException("<include /> can only be used inside of a ViewGroup");
         }
 
+        LayoutInflater.consumeChildElements(parser);
+    }
+
+    /**
+     * <strong>Note:</strong> default visibility so that
+     * LayoutInflater_Delegate can call it.
+     */
+    final static void consumeChildElements(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int type;
         final int currentDepth = parser.getDepth();
         while (((type = parser.next()) != XmlPullParser.END_TAG ||
                 parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
diff --git a/core/java/android/view/PhoneFallbackEventHandler.java b/core/java/android/view/PhoneFallbackEventHandler.java
index fbf5732..350650d 100644
--- a/core/java/android/view/PhoneFallbackEventHandler.java
+++ b/core/java/android/view/PhoneFallbackEventHandler.java
@@ -25,8 +25,13 @@
 import android.media.AudioManager;
 import android.media.session.MediaSessionLegacyHelper;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
+import android.view.View;
+import android.view.HapticFeedbackConstants;
+import android.view.FallbackEventHandler;
+import android.view.KeyEvent;
 
 /**
  * @hide
@@ -112,15 +117,20 @@
                     dispatcher.startTracking(event, this);
                 } else if (event.isLongPress() && dispatcher.isTracking(event)) {
                     dispatcher.performedLongPress(event);
-                    mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-                    // launch the VoiceDialer
-                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    try {
-                        sendCloseSystemWindows();
-                        mContext.startActivity(intent);
-                    } catch (ActivityNotFoundException e) {
-                        startCallActivity();
+                    if (isUserSetupComplete()) {
+                        mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+                        // launch the VoiceDialer
+                        Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
+                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        try {
+                            sendCloseSystemWindows();
+                            mContext.startActivity(intent);
+                        } catch (ActivityNotFoundException e) {
+                            startCallActivity();
+                        }
+                    } else {
+                        Log.i(TAG, "Not starting call activity because user "
+                                + "setup is in progress.");
                     }
                 }
                 return true;
@@ -134,13 +144,18 @@
                     dispatcher.startTracking(event, this);
                 } else if (event.isLongPress() && dispatcher.isTracking(event)) {
                     dispatcher.performedLongPress(event);
-                    mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-                    sendCloseSystemWindows();
-                    // Broadcast an intent that the Camera button was longpressed
-                    Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
-                    intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
-                    mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF,
-                            null, null, null, 0, null, null);
+                    if (isUserSetupComplete()) {
+                        mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+                        sendCloseSystemWindows();
+                        // Broadcast an intent that the Camera button was longpressed
+                        Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
+                        intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
+                        mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF,
+                                null, null, null, 0, null, null);
+                    } else {
+                        Log.i(TAG, "Not dispatching CAMERA long press because user "
+                                + "setup is in progress.");
+                    }
                 }
                 return true;
             }
@@ -155,21 +170,26 @@
                     Configuration config = mContext.getResources().getConfiguration();
                     if (config.keyboard == Configuration.KEYBOARD_NOKEYS
                             || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
-                        // launch the search activity
-                        Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
-                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        try {
-                            mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-                            sendCloseSystemWindows();
-                            getSearchManager().stopSearch();
-                            mContext.startActivity(intent);
-                            // Only clear this if we successfully start the
-                            // activity; otherwise we will allow the normal short
-                            // press action to be performed.
-                            dispatcher.performedLongPress(event);
-                            return true;
-                        } catch (ActivityNotFoundException e) {
-                            // Ignore
+                        if (isUserSetupComplete()) {
+                            // launch the search activity
+                            Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
+                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            try {
+                                mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+                                sendCloseSystemWindows();
+                                getSearchManager().stopSearch();
+                                mContext.startActivity(intent);
+                                // Only clear this if we successfully start the
+                                // activity; otherwise we will allow the normal short
+                                // press action to be performed.
+                                dispatcher.performedLongPress(event);
+                                return true;
+                            } catch (ActivityNotFoundException e) {
+                                // Ignore
+                            }
+                        } else {
+                            Log.i(TAG, "Not dispatching SEARCH long press because user "
+                                    + "setup is in progress.");
                         }
                     }
                 }
@@ -181,7 +201,7 @@
 
     boolean onKeyUp(int keyCode, KeyEvent event) {
         if (DEBUG) {
-            Slog.d(TAG, "up " + keyCode);
+            Log.d(TAG, "up " + keyCode);
         }
         final KeyEvent.DispatcherState dispatcher = mView.getKeyDispatcherState();
         if (dispatcher != null) {
@@ -229,7 +249,12 @@
                     break;
                 }
                 if (event.isTracking() && !event.isCanceled()) {
-                    startCallActivity();
+                    if (isUserSetupComplete()) {
+                        startCallActivity();
+                    } else {
+                        Log.i(TAG, "Not starting call activity because user "
+                                + "setup is in progress.");
+                    }
                 }
                 return true;
             }
@@ -244,7 +269,7 @@
         try {
             mContext.startActivity(intent);
         } catch (ActivityNotFoundException e) {
-            Slog.w(TAG, "No activity found for android.intent.action.CALL_BUTTON.");
+            Log.w(TAG, "No activity found for android.intent.action.CALL_BUTTON.");
         }
     }
 
@@ -284,5 +309,10 @@
     private void handleMediaKeyEvent(KeyEvent keyEvent) {
         MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(keyEvent, false);
     }
+
+    private boolean isUserSetupComplete() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+    }
 }
 
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 05796bb..cb32697 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -28,6 +28,7 @@
 import android.os.UserHandle;
 
 import com.android.internal.R;
+import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.view.RootViewSurfaceTaker;
 import com.android.internal.view.StandaloneActionMode;
 import com.android.internal.view.menu.ContextMenuBuilder;
@@ -64,6 +65,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.transition.Scene;
 import android.transition.Transition;
 import android.transition.TransitionInflater;
@@ -125,7 +127,7 @@
     TypedValue mFixedWidthMinor;
     TypedValue mFixedHeightMajor;
     TypedValue mFixedHeightMinor;
-    TypedValue mOutsetBottom;
+    int mOutsetBottomPx;
 
     // This is the top-level view of the window, containing the window decor.
     private DecorView mDecor;
@@ -2368,12 +2370,10 @@
 
         @Override
         public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
-            if (mOutsetBottom != null) {
-                final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
-                int bottom = (int) mOutsetBottom.getDimension(metrics);
+            if (mOutsetBottomPx != 0) {
                 WindowInsets newInsets = insets.replaceSystemWindowInsets(
                         insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
-                        insets.getSystemWindowInsetRight(), bottom);
+                        insets.getSystemWindowInsetRight(), mOutsetBottomPx);
                 return super.dispatchApplyWindowInsets(newInsets);
             } else {
                 return super.dispatchApplyWindowInsets(insets);
@@ -2592,12 +2592,11 @@
                 }
             }
 
-            if (mOutsetBottom != null) {
+            if (mOutsetBottomPx != 0) {
                 int mode = MeasureSpec.getMode(heightMeasureSpec);
                 if (mode != MeasureSpec.UNSPECIFIED) {
-                    int outset = (int) mOutsetBottom.getDimension(metrics);
                     int height = MeasureSpec.getSize(heightMeasureSpec);
-                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + outset, mode);
+                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + mOutsetBottomPx, mode);
                 }
             }
 
@@ -3472,10 +3471,9 @@
             final boolean shouldUseBottomOutset =
                     display.getDisplayId() == Display.DEFAULT_DISPLAY
                             || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0;
-            if (shouldUseBottomOutset && a.hasValue(R.styleable.Window_windowOutsetBottom)) {
-                if (mOutsetBottom == null) mOutsetBottom = new TypedValue();
-                a.getValue(R.styleable.Window_windowOutsetBottom,
-                        mOutsetBottom);
+            if (shouldUseBottomOutset) {
+                mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
+                        getContext().getResources().getDisplayMetrics(), a);
             }
         }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e790d4c..234de40 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -40,7 +40,6 @@
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.media.AudioManager;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
@@ -77,6 +76,7 @@
 
 import com.android.internal.R;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.view.BaseSurfaceHolder;
 import com.android.internal.view.RootViewSurfaceTaker;
 
@@ -120,8 +120,10 @@
     private static final String PROPERTY_PROFILE_RENDERING = "viewroot.profile_rendering";
     private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media";
 
-    // property used by emulator to determine display shape
+    // properties used by emulator to determine display shape
     public static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
+    public static final String PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX =
+            "ro.emu.win_outset_bottom_px";
 
     /**
      * Maximum time we allow the user to roll the trackball enough to generate
@@ -334,8 +336,6 @@
     /** Set to true once doDie() has been called. */
     private boolean mRemoved;
 
-    private boolean mIsEmulator;
-    private boolean mIsCircularEmulator;
     private final boolean mWindowIsRound;
 
     /**
@@ -392,8 +392,7 @@
         mChoreographer = Choreographer.getInstance();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
         loadSystemProperties();
-        mWindowIsRound = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_windowIsRound);
+        mWindowIsRound = ScreenShapeHelper.getWindowIsRound(context.getResources());
     }
 
     public static void addFirstDrawHandler(Runnable callback) {
@@ -1248,9 +1247,8 @@
                 contentInsets = mPendingContentInsets;
                 stableInsets = mPendingStableInsets;
             }
-            final boolean isRound = (mIsEmulator && mIsCircularEmulator) || mWindowIsRound;
             mLastWindowInsets = new WindowInsets(contentInsets,
-                    null /* windowDecorInsets */, stableInsets, isRound);
+                    null /* windowDecorInsets */, stableInsets, mWindowIsRound);
         }
         return mLastWindowInsets;
     }
@@ -5590,11 +5588,6 @@
                         mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
                     }
                 }
-
-                // detect emulator
-                mIsEmulator = Build.HARDWARE.contains("goldfish");
-                mIsCircularEmulator =
-                        SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false);
             }
         });
     }
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 5c05b5a..6feb94b 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -16,6 +16,7 @@
 */
 package android.widget;
 
+import android.os.UserHandle;
 import com.android.internal.R;
 
 import android.app.AlertDialog;
@@ -243,7 +244,8 @@
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
                     PackageManager pm = getContext().getPackageManager();
-                    pm.revokePermission(mPackageName, mPerm.name);
+                    pm.revokePermission(mPackageName, mPerm.name,
+                            new UserHandle(mContext.getUserId()));
                     PermissionItemView.this.setVisibility(View.GONE);
                 }
             };
@@ -298,7 +300,7 @@
             }
             extractPerms(info, permSet, installedPkgInfo);
         }
-        // Get permissions related to  shared user if any
+        // Get permissions related to shared user if any
         if (info.sharedUserId != null) {
             int sharedUid;
             try {
@@ -358,7 +360,7 @@
             String permName = strList[i];
             // If we are only looking at an existing app, then we only
             // care about permissions that have actually been granted to it.
-            if (installedPkgInfo != null && info == installedPkgInfo) {
+            if (installedPkgInfo != null && info != installedPkgInfo) {
                 if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
                     continue;
                 }
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 5bc16cb..2aaa356 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -18,6 +18,7 @@
 
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.StyleRes;
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -31,6 +32,7 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 
@@ -118,7 +120,9 @@
      * @param count The shown week count.
      *
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setShownWeekCount(int count) {
         mDelegate.setShownWeekCount(count);
     }
@@ -129,7 +133,9 @@
      * @return The shown week count.
      *
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public int getShownWeekCount() {
         return mDelegate.getShownWeekCount();
     }
@@ -140,7 +146,9 @@
      * @param color The week background color.
      *
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setSelectedWeekBackgroundColor(@ColorInt int color) {
         mDelegate.setSelectedWeekBackgroundColor(color);
     }
@@ -151,8 +159,10 @@
      * @return The week background color.
      *
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
     @ColorInt
+    @Deprecated
     public int getSelectedWeekBackgroundColor() {
         return mDelegate.getSelectedWeekBackgroundColor();
     }
@@ -163,7 +173,9 @@
      * @param color The focused month date color.
      *
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setFocusedMonthDateColor(@ColorInt int color) {
         mDelegate.setFocusedMonthDateColor(color);
     }
@@ -174,8 +186,10 @@
      * @return The focused month date color.
      *
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
     @ColorInt
+    @Deprecated
     public int getFocusedMonthDateColor() {
         return mDelegate.getFocusedMonthDateColor();
     }
@@ -186,7 +200,9 @@
      * @param color A not focused month date color.
      *
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setUnfocusedMonthDateColor(@ColorInt int color) {
         mDelegate.setUnfocusedMonthDateColor(color);
     }
@@ -197,8 +213,10 @@
      * @return A not focused month date color.
      *
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
     @ColorInt
+    @Deprecated
     public int getUnfocusedMonthDateColor() {
         return mDelegate.getUnfocusedMonthDateColor();
     }
@@ -209,7 +227,9 @@
      * @param color The week number color.
      *
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setWeekNumberColor(@ColorInt int color) {
         mDelegate.setWeekNumberColor(color);
     }
@@ -220,8 +240,10 @@
      * @return The week number color.
      *
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
     @ColorInt
+    @Deprecated
     public int getWeekNumberColor() {
         return mDelegate.getWeekNumberColor();
     }
@@ -232,7 +254,9 @@
      * @param color The week separator color.
      *
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setWeekSeparatorLineColor(@ColorInt int color) {
         mDelegate.setWeekSeparatorLineColor(color);
     }
@@ -243,8 +267,10 @@
      * @return The week separator color.
      *
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
+     * @deprecated No longer used by Material-style CalendarView.
      */
     @ColorInt
+    @Deprecated
     public int getWeekSeparatorLineColor() {
         return mDelegate.getWeekSeparatorLineColor();
     }
@@ -256,7 +282,9 @@
      * @param resourceId The vertical bar drawable resource id.
      *
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setSelectedDateVerticalBar(@DrawableRes int resourceId) {
         mDelegate.setSelectedDateVerticalBar(resourceId);
     }
@@ -268,7 +296,9 @@
      * @param drawable The vertical bar drawable.
      *
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public void setSelectedDateVerticalBar(Drawable drawable) {
         mDelegate.setSelectedDateVerticalBar(drawable);
     }
@@ -278,7 +308,9 @@
      * the end of the selected date.
      *
      * @return The vertical bar drawable.
+     * @deprecated No longer used by Material-style CalendarView.
      */
+    @Deprecated
     public Drawable getSelectedDateVerticalBar() {
         return mDelegate.getSelectedDateVerticalBar();
     }
@@ -519,29 +551,36 @@
         void setShownWeekCount(int count);
         int getShownWeekCount();
 
-        void setSelectedWeekBackgroundColor(int color);
+        void setSelectedWeekBackgroundColor(@ColorInt int color);
+        @ColorInt
         int getSelectedWeekBackgroundColor();
 
-        void setFocusedMonthDateColor(int color);
+        void setFocusedMonthDateColor(@ColorInt int color);
+        @ColorInt
         int getFocusedMonthDateColor();
 
-        void setUnfocusedMonthDateColor(int color);
+        void setUnfocusedMonthDateColor(@ColorInt int color);
+        @ColorInt
         int getUnfocusedMonthDateColor();
 
-        void setWeekNumberColor(int color);
+        void setWeekNumberColor(@ColorInt int color);
+        @ColorInt
         int getWeekNumberColor();
 
-        void setWeekSeparatorLineColor(int color);
+        void setWeekSeparatorLineColor(@ColorInt int color);
+        @ColorInt
         int getWeekSeparatorLineColor();
 
-        void setSelectedDateVerticalBar(int resourceId);
+        void setSelectedDateVerticalBar(@DrawableRes int resourceId);
         void setSelectedDateVerticalBar(Drawable drawable);
         Drawable getSelectedDateVerticalBar();
 
-        void setWeekDayTextAppearance(int resourceId);
+        void setWeekDayTextAppearance(@StyleRes int resourceId);
+        @StyleRes
         int getWeekDayTextAppearance();
 
-        void setDateTextAppearance(int resourceId);
+        void setDateTextAppearance(@StyleRes int resourceId);
+        @StyleRes
         int getDateTextAppearance();
 
         void setMinDate(long minDate);
@@ -569,18 +608,12 @@
      * An abstract class which can be used as a start for CalendarView implementations
      */
     abstract static class AbstractCalendarViewDelegate implements CalendarViewDelegate {
-        /** String for parsing dates. */
-        private static final String DATE_FORMAT = "MM/dd/yyyy";
-
         /** The default minimal date. */
         protected static final String DEFAULT_MIN_DATE = "01/01/1900";
 
         /** The default maximal date. */
         protected static final String DEFAULT_MAX_DATE = "01/01/2100";
 
-        /** Date format for parsing dates. */
-        protected static final DateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);
-
         protected CalendarView mDelegator;
         protected Context mContext;
         protected Locale mCurrentLocale;
@@ -600,21 +633,131 @@
             mCurrentLocale = locale;
         }
 
-        /**
-         * Parses the given <code>date</code> and in case of success sets
-         * the result to the <code>outDate</code>.
-         *
-         * @return True if the date was parsed.
-         */
-        protected boolean parseDate(String date, Calendar outDate) {
-            try {
-                outDate.setTime(DATE_FORMATTER.parse(date));
-                return true;
-            } catch (ParseException e) {
-                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
-                return false;
-            }
+        @Override
+        public void setShownWeekCount(int count) {
+            // Deprecated.
+        }
+
+        @Override
+        public int getShownWeekCount() {
+            // Deprecated.
+            return 0;
+        }
+
+        @Override
+        public void setSelectedWeekBackgroundColor(@ColorInt int color) {
+            // Deprecated.
+        }
+
+        @ColorInt
+        @Override
+        public int getSelectedWeekBackgroundColor() {
+            return 0;
+        }
+
+        @Override
+        public void setFocusedMonthDateColor(@ColorInt int color) {
+            // Deprecated.
+        }
+
+        @ColorInt
+        @Override
+        public int getFocusedMonthDateColor() {
+            return 0;
+        }
+
+        @Override
+        public void setUnfocusedMonthDateColor(@ColorInt int color) {
+            // Deprecated.
+        }
+
+        @ColorInt
+        @Override
+        public int getUnfocusedMonthDateColor() {
+            return 0;
+        }
+
+        @Override
+        public void setWeekNumberColor(@ColorInt int color) {
+            // Deprecated.
+        }
+
+        @ColorInt
+        @Override
+        public int getWeekNumberColor() {
+            // Deprecated.
+            return 0;
+        }
+
+        @Override
+        public void setWeekSeparatorLineColor(@ColorInt int color) {
+            // Deprecated.
+        }
+
+        @ColorInt
+        @Override
+        public int getWeekSeparatorLineColor() {
+            // Deprecated.
+            return 0;
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(@DrawableRes int resId) {
+            // Deprecated.
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(Drawable drawable) {
+            // Deprecated.
+        }
+
+        @Override
+        public Drawable getSelectedDateVerticalBar() {
+            // Deprecated.
+            return null;
+        }
+
+        @Override
+        public void setShowWeekNumber(boolean showWeekNumber) {
+            // Deprecated.
+        }
+
+        @Override
+        public boolean getShowWeekNumber() {
+            // Deprecated.
+            return false;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            // Nothing to do here, configuration changes are already propagated
+            // by ViewGroup.
         }
     }
 
+    /** String for parsing dates. */
+    private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+    /** Date format for parsing dates. */
+    private static final DateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);
+
+    /**
+     * Utility method for the date format used by CalendarView's min/max date.
+     *
+     * @hide Use only as directed. For internal use only.
+     */
+    public static boolean parseDate(String date, Calendar outDate) {
+        if (date == null || date.isEmpty()) {
+            return false;
+        }
+
+        try {
+            final Date parsedDate = DATE_FORMATTER.parse(date);
+            outDate.setTime(parsedDate);
+            return true;
+        } catch (ParseException e) {
+            Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index 2ab3548..6ab3828 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -27,7 +27,6 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -267,12 +266,12 @@
         mFirstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
                 LocaleData.get(Locale.getDefault()).firstDayOfWeek);
         final String minDate = a.getString(R.styleable.CalendarView_minDate);
-        if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
-            parseDate(DEFAULT_MIN_DATE, mMinDate);
+        if (!CalendarView.parseDate(minDate, mMinDate)) {
+            CalendarView.parseDate(DEFAULT_MIN_DATE, mMinDate);
         }
         final String maxDate = a.getString(R.styleable.CalendarView_maxDate);
-        if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
-            parseDate(DEFAULT_MAX_DATE, mMaxDate);
+        if (!CalendarView.parseDate(maxDate, mMaxDate)) {
+            CalendarView.parseDate(DEFAULT_MAX_DATE, mMaxDate);
         }
         if (mMaxDate.before(mMinDate)) {
             throw new IllegalArgumentException("Max date cannot be before min date.");
diff --git a/core/java/android/widget/CalendarViewMaterialDelegate.java b/core/java/android/widget/CalendarViewMaterialDelegate.java
index b0f3740..7bce756 100644
--- a/core/java/android/widget/CalendarViewMaterialDelegate.java
+++ b/core/java/android/widget/CalendarViewMaterialDelegate.java
@@ -16,20 +16,11 @@
 
 package android.widget;
 
-import com.android.internal.R;
-
+import android.annotation.StyleRes;
 import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.MathUtils;
 
 import java.util.Calendar;
-import java.util.Locale;
-
-import libcore.icu.LocaleData;
 
 class CalendarViewMaterialDelegate extends CalendarView.AbstractCalendarViewDelegate {
     private final DayPickerView mDayPickerView;
@@ -40,142 +31,32 @@
             int defStyleAttr, int defStyleRes) {
         super(delegator, context);
 
-        final TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.CalendarView, defStyleAttr, defStyleRes);
-        final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
-                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
-
-        final long minDate = parseDateToMillis(a.getString(
-                R.styleable.CalendarView_minDate), DEFAULT_MIN_DATE);
-        final long maxDate = parseDateToMillis(a.getString(
-                R.styleable.CalendarView_maxDate), DEFAULT_MAX_DATE);
-        if (maxDate < minDate) {
-            throw new IllegalArgumentException("max date cannot be before min date");
-        }
-
-        final long setDate = MathUtils.constrain(System.currentTimeMillis(), minDate, maxDate);
-        final int dateTextAppearanceResId = a.getResourceId(
-                R.styleable.CalendarView_dateTextAppearance,
-                R.style.TextAppearance_DeviceDefault_Small);
-
-        a.recycle();
-
-        mDayPickerView = new DayPickerView(context);
-        mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
-        mDayPickerView.setCalendarTextAppearance(dateTextAppearanceResId);
-        mDayPickerView.setMinDate(minDate);
-        mDayPickerView.setMaxDate(maxDate);
-        mDayPickerView.setDate(setDate, false, true);
+        mDayPickerView = new DayPickerView(context, attrs, defStyleAttr, defStyleRes);
         mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
 
         delegator.addView(mDayPickerView);
     }
 
-    private long parseDateToMillis(String dateStr, String defaultDateStr) {
-        final Calendar tempCalendar = Calendar.getInstance();
-        if (TextUtils.isEmpty(dateStr) || !parseDate(dateStr, tempCalendar)) {
-            parseDate(defaultDateStr, tempCalendar);
-        }
-        return tempCalendar.getTimeInMillis();
-    }
-
     @Override
-    public void setShownWeekCount(int count) {
-        // Deprecated.
+    public void setWeekDayTextAppearance(@StyleRes int resId) {
+        mDayPickerView.setDayOfWeekTextAppearance(resId);
     }
 
-    @Override
-    public int getShownWeekCount() {
-        // Deprecated.
-        return 0;
-    }
-
-    @Override
-    public void setSelectedWeekBackgroundColor(int color) {
-        // TODO: Should use a ColorStateList. Deprecate?
-    }
-
-    @Override
-    public int getSelectedWeekBackgroundColor() {
-        return 0;
-    }
-
-    @Override
-    public void setFocusedMonthDateColor(int color) {
-        // TODO: Should use a ColorStateList. Deprecate?
-    }
-
-    @Override
-    public int getFocusedMonthDateColor() {
-        return 0;
-    }
-
-    @Override
-    public void setUnfocusedMonthDateColor(int color) {
-        // TODO: Should use a ColorStateList. Deprecate?
-    }
-
-    @Override
-    public int getUnfocusedMonthDateColor() {
-        return 0;
-    }
-
-    @Override
-    public void setWeekDayTextAppearance(int resourceId) {
-
-    }
-
+    @StyleRes
     @Override
     public int getWeekDayTextAppearance() {
-        return 0;
+        return mDayPickerView.getDayOfWeekTextAppearance();
     }
 
     @Override
-    public void setDateTextAppearance(int resourceId) {
-
+    public void setDateTextAppearance(@StyleRes int resId) {
+        mDayPickerView.setDayTextAppearance(resId);
     }
 
+    @StyleRes
     @Override
     public int getDateTextAppearance() {
-        return 0;
-    }
-
-    @Override
-    public void setWeekNumberColor(int color) {
-        // Deprecated.
-    }
-
-    @Override
-    public int getWeekNumberColor() {
-        // Deprecated.
-        return 0;
-    }
-
-    @Override
-    public void setWeekSeparatorLineColor(int color) {
-        // Deprecated.
-    }
-
-    @Override
-    public int getWeekSeparatorLineColor() {
-        // Deprecated.
-        return 0;
-    }
-
-    @Override
-    public void setSelectedDateVerticalBar(int resourceId) {
-        // Deprecated.
-    }
-
-    @Override
-    public void setSelectedDateVerticalBar(Drawable drawable) {
-        // Deprecated.
-    }
-
-    @Override
-    public Drawable getSelectedDateVerticalBar() {
-        // Deprecated.
-        return null;
+        return mDayPickerView.getDayTextAppearance();
     }
 
     @Override
@@ -199,17 +80,6 @@
     }
 
     @Override
-    public void setShowWeekNumber(boolean showWeekNumber) {
-        // Deprecated.
-    }
-
-    @Override
-    public boolean getShowWeekNumber() {
-        // Deprecated.
-        return false;
-    }
-
-    @Override
     public void setFirstDayOfWeek(int firstDayOfWeek) {
         mDayPickerView.setFirstDayOfWeek(firstDayOfWeek);
     }
@@ -221,12 +91,12 @@
 
     @Override
     public void setDate(long date) {
-        mDayPickerView.setDate(date, true, false);
+        mDayPickerView.setDate(date, true);
     }
 
     @Override
     public void setDate(long date, boolean animate, boolean center) {
-        mDayPickerView.setDate(date, animate, center);
+        mDayPickerView.setDate(date, animate);
     }
 
     @Override
@@ -239,12 +109,6 @@
         mOnDateChangeListener = listener;
     }
 
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        // Nothing to do here, configuration changes are already propagated
-        // by ViewGroup.
-    }
-
     private final DayPickerView.OnDaySelectedListener mOnDaySelectedListener =
             new DayPickerView.OnDaySelectedListener() {
         @Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 45998f7..5f5943f 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -98,7 +98,7 @@
     private final DatePickerDelegate mDelegate;
 
     /**
-     * The callback used to indicate the user changes\d the date.
+     * The callback used to indicate the user changed the date.
      */
     public interface OnDateChangedListener {
 
@@ -348,9 +348,13 @@
     }
 
     /**
-     * Gets whether the {@link CalendarView} is shown.
+     * Returns whether the {@link CalendarView} is shown.
+     * <p>
+     * <strong>Note:</strong> This method returns {@code false} when the
+     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
+     * to {@code calendar}.
      *
-     * @return True if the calendar view is shown.
+     * @return {@code true} if the calendar view is shown
      * @see #getCalendarView()
      */
     public boolean getCalendarViewShown() {
@@ -358,13 +362,13 @@
     }
 
     /**
-     * Gets the {@link CalendarView}.
+     * Returns the {@link CalendarView} used by this picker.
      * <p>
-     * This method returns {@code null} when the
+     * <strong>Note:</strong> This method returns {@code null} when the
      * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
      * to {@code calendar}.
      *
-     * @return The calendar view.
+     * @return the calendar view
      * @see #getCalendarViewShown()
      */
     public CalendarView getCalendarView() {
@@ -374,20 +378,25 @@
     /**
      * Sets whether the {@link CalendarView} is shown.
      * <p>
-     * Calling this method has no effect when the
+     * <strong>Note:</strong> Calling this method has no effect when the
      * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
      * to {@code calendar}.
      *
-     * @param shown True if the calendar view is to be shown.
+     * @param shown {@code true} to show the calendar view, {@code false} to
+     *              hide it
      */
     public void setCalendarViewShown(boolean shown) {
         mDelegate.setCalendarViewShown(shown);
     }
 
     /**
-     * Gets whether the spinners are shown.
+     * Returns whether the spinners are shown.
+     * <p>
+     * <strong>Note:</strong> his method returns {@code false} when the
+     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
+     * to {@code calendar}.
      *
-     * @return True if the spinners are shown.
+     * @return {@code true} if the spinners are shown
      */
     public boolean getSpinnersShown() {
         return mDelegate.getSpinnersShown();
@@ -395,8 +404,13 @@
 
     /**
      * Sets whether the spinners are shown.
+     * <p>
+     * Calling this method has no effect when the
+     * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set
+     * to {@code calendar}.
      *
-     * @param shown True if the spinners are to be shown.
+     * @param shown {@code true} to show the spinners, {@code false} to hide
+     *              them
      */
     public void setSpinnersShown(boolean shown) {
         mDelegate.setSpinnersShown(shown);
@@ -489,15 +503,14 @@
             mDelegator = delegator;
             mContext = context;
 
-            // initialization based on locale
             setCurrentLocale(Locale.getDefault());
         }
 
         protected void setCurrentLocale(Locale locale) {
-            if (locale.equals(mCurrentLocale)) {
-                return;
+            if (!locale.equals(mCurrentLocale)) {
+                mCurrentLocale = locale;
+                onLocaleChanged(locale);
             }
-            mCurrentLocale = locale;
         }
 
         @Override
@@ -510,6 +523,10 @@
                 mValidationCallback.onValidationChanged(valid);
             }
         }
+
+        protected void onLocaleChanged(Locale locale) {
+            // Stub.
+        }
     }
 
     /**
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 0e3ec7f..7b8a979 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -26,90 +27,84 @@
 import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
+import android.util.StateSet;
 import android.view.HapticFeedbackConstants;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
+import android.widget.DayPickerView.OnDaySelectedListener;
+import android.widget.YearPickerView.OnYearSelectedListener;
 
 import com.android.internal.R;
-import com.android.internal.widget.AccessibleDateAnimator;
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.HashSet;
 import java.util.Locale;
 
 /**
  * A delegate for picking up a date (day / month / year).
  */
-class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate implements
-        View.OnClickListener, DatePickerController {
+class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate {
+
     private static final int USE_LOCALE = 0;
 
     private static final int UNINITIALIZED = -1;
-    private static final int MONTH_AND_DAY_VIEW = 0;
-    private static final int YEAR_VIEW = 1;
+    private static final int VIEW_MONTH_DAY = 0;
+    private static final int VIEW_YEAR = 1;
 
     private static final int DEFAULT_START_YEAR = 1900;
     private static final int DEFAULT_END_YEAR = 2100;
 
     private static final int ANIMATION_DURATION = 300;
 
-    private static final int MONTH_INDEX = 0;
-    private static final int DAY_INDEX = 1;
-    private static final int YEAR_INDEX = 2;
+    public static final int[] ATTRS_TEXT_COLOR = new int[]{com.android.internal.R.attr.textColor};
 
-    private SimpleDateFormat mYearFormat = new SimpleDateFormat("y", Locale.getDefault());
-    private SimpleDateFormat mDayFormat = new SimpleDateFormat("d", Locale.getDefault());
+    public static final int[] ATTRS_DISABLED_ALPHA = new int[]{
+            com.android.internal.R.attr.disabledAlpha};
 
-    private TextView mDayOfWeekView;
+    private SimpleDateFormat mYearFormat;
+    private SimpleDateFormat mMonthDayFormat;
 
-    /** Layout that contains the current month, day, and year. */
-    private LinearLayout mMonthDayYearLayout;
+    // Top-level container.
+    private ViewGroup mContainer;
 
-    /** Clickable layout that contains the current day and year. */
-    private LinearLayout mMonthAndDayLayout;
+    // Header views.
+    private TextView mHeaderYear;
+    private TextView mHeaderMonthDay;
 
-    private TextView mHeaderMonthTextView;
-    private TextView mHeaderDayOfMonthTextView;
-    private TextView mHeaderYearTextView;
+    // Picker views.
+    private ViewAnimator mAnimator;
     private DayPickerView mDayPickerView;
     private YearPickerView mYearPickerView;
 
-    private boolean mIsEnabled = true;
-
     // Accessibility strings.
-    private String mDayPickerDescription;
     private String mSelectDay;
-    private String mYearPickerDescription;
     private String mSelectYear;
 
-    private AccessibleDateAnimator mAnimator;
-
     private DatePicker.OnDateChangedListener mDateChangedListener;
 
     private int mCurrentView = UNINITIALIZED;
 
-    private Calendar mCurrentDate;
-    private Calendar mTempDate;
-    private Calendar mMinDate;
-    private Calendar mMaxDate;
+    private final Calendar mCurrentDate;
+    private final Calendar mTempDate;
+    private final Calendar mMinDate;
+    private final Calendar mMaxDate;
 
     private int mFirstDayOfWeek = USE_LOCALE;
 
-    private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
-
     public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
         super(delegator, context);
 
-        final Locale locale = Locale.getDefault();
-        mMinDate = getCalendarForLocale(mMinDate, locale);
-        mMaxDate = getCalendarForLocale(mMaxDate, locale);
-        mTempDate = getCalendarForLocale(mMaxDate, locale);
-        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
+        final Locale locale = mCurrentLocale;
+        mCurrentDate = Calendar.getInstance(locale);
+        mTempDate = Calendar.getInstance(locale);
+        mMinDate = Calendar.getInstance(locale);
+        mMaxDate = Calendar.getInstance(locale);
 
         mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
         mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
@@ -120,71 +115,64 @@
         final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         final int layoutResourceId = a.getResourceId(
-                R.styleable.DatePicker_internalLayout, R.layout.date_picker_holo);
-        final View mainView = inflater.inflate(layoutResourceId, null);
-        mDelegator.addView(mainView);
+                R.styleable.DatePicker_internalLayout, R.layout.date_picker_material);
 
-        mDayOfWeekView = (TextView) mainView.findViewById(R.id.date_picker_header);
+        // Set up and attach container.
+        mContainer = (ViewGroup) inflater.inflate(layoutResourceId, mDelegator);
 
-        // Layout that contains the current date and day name header.
-        final LinearLayout dateLayout = (LinearLayout) mainView.findViewById(
-                R.id.day_picker_selector_layout);
-        mMonthDayYearLayout = (LinearLayout) mainView.findViewById(
-                R.id.date_picker_month_day_year_layout);
-        mMonthAndDayLayout = (LinearLayout) mainView.findViewById(
-                R.id.date_picker_month_and_day_layout);
-        mMonthAndDayLayout.setOnClickListener(this);
-        mHeaderMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_month);
-        mHeaderDayOfMonthTextView = (TextView) mainView.findViewById(R.id.date_picker_day);
-        mHeaderYearTextView = (TextView) mainView.findViewById(R.id.date_picker_year);
-        mHeaderYearTextView.setOnClickListener(this);
+        // Set up header views.
+        final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header);
+        mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year);
+        mHeaderYear.setOnClickListener(mOnHeaderClickListener);
+        mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date);
+        mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener);
 
-        // Obtain default highlight color from the theme.
-        final int defaultHighlightColor = mHeaderYearTextView.getHighlightColor();
+        // For the sake of backwards compatibility, attempt to extract the text
+        // color from the header month text appearance. If it's set, we'll let
+        // that override the "real" header text color.
+        ColorStateList headerTextColor = null;
 
-        // Use Theme attributes if possible
-        final int dayOfWeekTextAppearanceResId = a.getResourceId(
-                R.styleable.DatePicker_dayOfWeekTextAppearance, 0);
-        if (dayOfWeekTextAppearanceResId != 0) {
-            mDayOfWeekView.setTextAppearance(context, dayOfWeekTextAppearanceResId);
-        }
-
-        mDayOfWeekView.setBackground(a.getDrawable(R.styleable.DatePicker_dayOfWeekBackground));
-
-        dateLayout.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
-
-        final int monthTextAppearanceResId = a.getResourceId(
+        @SuppressWarnings("deprecation")
+        final int monthHeaderTextAppearance = a.getResourceId(
                 R.styleable.DatePicker_headerMonthTextAppearance, 0);
-        if (monthTextAppearanceResId != 0) {
-            mHeaderMonthTextView.setTextAppearance(context, monthTextAppearanceResId);
+        if (monthHeaderTextAppearance != 0) {
+            final TypedArray textAppearance = mContext.obtainStyledAttributes(null,
+                    ATTRS_TEXT_COLOR, 0, monthHeaderTextAppearance);
+            final ColorStateList legacyHeaderTextColor = textAppearance.getColorStateList(0);
+            headerTextColor = applyLegacyColorFixes(legacyHeaderTextColor);
+            textAppearance.recycle();
         }
 
-        final int dayOfMonthTextAppearanceResId = a.getResourceId(
-                R.styleable.DatePicker_headerDayOfMonthTextAppearance, 0);
-        if (dayOfMonthTextAppearanceResId != 0) {
-            mHeaderDayOfMonthTextView.setTextAppearance(context, dayOfMonthTextAppearanceResId);
+        if (headerTextColor == null) {
+            headerTextColor = a.getColorStateList(R.styleable.DatePicker_headerTextColor);
         }
 
-        final int headerYearTextAppearanceResId = a.getResourceId(
-                R.styleable.DatePicker_headerYearTextAppearance, 0);
-        if (headerYearTextAppearanceResId != 0) {
-            mHeaderYearTextView.setTextAppearance(context, headerYearTextAppearanceResId);
+        if (headerTextColor != null) {
+            mHeaderYear.setTextColor(headerTextColor);
+            mHeaderMonthDay.setTextColor(headerTextColor);
         }
 
-        mDayPickerView = new DayPickerView(mContext);
+        // Set up header background, if available.
+        if (a.hasValueOrEmpty(R.styleable.DatePicker_headerBackground)) {
+            header.setBackground(a.getDrawable(R.styleable.DatePicker_headerBackground));
+        }
+
+        // Set up picker container.
+        mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator);
+
+        // Set up day picker view.
+        mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker);
         mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
         mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
         mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
         mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
         mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
 
-        mYearPickerView = new YearPickerView(mContext);
-        mYearPickerView.init(this);
+        // Set up year picker view.
+        mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
         mYearPickerView.setRange(mMinDate, mMaxDate);
-
-        final ColorStateList yearBackgroundColor = a.getColorStateList(
-                R.styleable.DatePicker_yearListSelectorColor);
-        mYearPickerView.setYearBackgroundColor(yearBackgroundColor);
+        mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
+        mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
 
         final int yearTextAppearanceResId = a.getResourceId(
                 R.styleable.DatePicker_yearListItemTextAppearance, 0);
@@ -192,170 +180,201 @@
             mYearPickerView.setYearTextAppearance(yearTextAppearanceResId);
         }
 
-        final ColorStateList calendarTextColor = a.getColorStateList(
-                R.styleable.DatePicker_calendarTextColor);
-        mDayPickerView.setCalendarTextColor(calendarTextColor);
+        final int yearActivatedTextAppearanceResId = a.getResourceId(
+                R.styleable.DatePicker_yearListItemActivatedTextAppearance, 0);
+        if (yearActivatedTextAppearanceResId != 0) {
+            mYearPickerView.setYearActivatedTextAppearance(yearActivatedTextAppearanceResId);
+        }
 
-        final ColorStateList calendarDayBackgroundColor = a.getColorStateList(
-                R.styleable.DatePicker_calendarDayBackgroundColor);
-        mDayPickerView.setCalendarDayBackgroundColor(calendarDayBackgroundColor);
+        a.recycle();
 
-        mDayPickerDescription = res.getString(R.string.day_picker_description);
+        // Set up content descriptions.
         mSelectDay = res.getString(R.string.select_day);
-        mYearPickerDescription = res.getString(R.string.year_picker_description);
         mSelectYear = res.getString(R.string.select_year);
 
-        mAnimator = (AccessibleDateAnimator) mainView.findViewById(R.id.animator);
-        mAnimator.addView(mDayPickerView);
-        mAnimator.addView(mYearPickerView);
-        mAnimator.setDateMillis(mCurrentDate.getTimeInMillis());
+        final Animation inAnim = new AlphaAnimation(0, 1);
+        inAnim.setDuration(ANIMATION_DURATION);
+        mAnimator.setInAnimation(inAnim);
 
-        final Animation animation = new AlphaAnimation(0.0f, 1.0f);
-        animation.setDuration(ANIMATION_DURATION);
-        mAnimator.setInAnimation(animation);
+        final Animation outAnim = new AlphaAnimation(1, 0);
+        outAnim.setDuration(ANIMATION_DURATION);
+        mAnimator.setOutAnimation(outAnim);
 
-        final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
-        animation2.setDuration(ANIMATION_DURATION);
-        mAnimator.setOutAnimation(animation2);
+        // Initialize for current locale. This also initializes the date, so no
+        // need to call onDateChanged.
+        onLocaleChanged(mCurrentLocale);
 
-        updateDisplay(false);
-        setCurrentView(MONTH_AND_DAY_VIEW);
+        setCurrentView(VIEW_MONTH_DAY);
     }
 
     /**
-     * Gets a calendar for locale bootstrapped with the value of a given calendar.
+     * The legacy text color might have been poorly defined. Ensures that it
+     * has an appropriate activated state, using the selected state if one
+     * exists or modifying the default text color otherwise.
      *
-     * @param oldCalendar The old calendar.
-     * @param locale The locale.
+     * @param color a legacy text color, or {@code null}
+     * @return a color state list with an appropriate activated state, or
+     *         {@code null} if a valid activated state could not be generated
      */
-    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-        if (oldCalendar == null) {
-            return Calendar.getInstance(locale);
-        } else {
-            final long currentTimeMillis = oldCalendar.getTimeInMillis();
-            Calendar newCalendar = Calendar.getInstance(locale);
-            newCalendar.setTimeInMillis(currentTimeMillis);
-            return newCalendar;
+    @Nullable
+    private ColorStateList applyLegacyColorFixes(@Nullable ColorStateList color) {
+        if (color == null || color.hasState(R.attr.state_activated)) {
+            return color;
         }
+
+        final int activatedColor;
+        final int defaultColor;
+        if (color.hasState(R.attr.state_selected)) {
+            activatedColor = color.getColorForState(StateSet.get(
+                    StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_SELECTED), 0);
+            defaultColor = color.getColorForState(StateSet.get(
+                    StateSet.VIEW_STATE_ENABLED), 0);
+        } else {
+            activatedColor = color.getDefaultColor();
+
+            // Generate a non-activated color using the disabled alpha.
+            final TypedArray ta = mContext.obtainStyledAttributes(ATTRS_DISABLED_ALPHA);
+            final float disabledAlpha = ta.getFloat(0, 0.30f);
+            defaultColor = multiplyAlphaComponent(activatedColor, disabledAlpha);
+        }
+
+        if (activatedColor == 0 || defaultColor == 0) {
+            // We somehow failed to obtain the colors.
+            return null;
+        }
+
+        final int[][] stateSet = new int[][] {{ R.attr.state_activated }, {}};
+        final int[] colors = new int[] { activatedColor, defaultColor };
+        return new ColorStateList(stateSet, colors);
+    }
+
+    private int multiplyAlphaComponent(int color, float alphaMod) {
+        final int srcRgb = color & 0xFFFFFF;
+        final int srcAlpha = (color >> 24) & 0xFF;
+        final int dstAlpha = (int) (srcAlpha * alphaMod + 0.5f);
+        return srcRgb | (dstAlpha << 24);
     }
 
     /**
-     * Compute the array representing the order of Month / Day / Year views in their layout.
-     * Will be used for I18N purpose as the order of them depends on the Locale.
+     * Listener called when the user selects a day in the day picker view.
      */
-    private int[] getMonthDayYearIndexes(String pattern) {
-        int[] result = new int[3];
+    private final OnDaySelectedListener mOnDaySelectedListener = new OnDaySelectedListener() {
+        @Override
+        public void onDaySelected(DayPickerView view, Calendar day) {
+            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
+            onDateChanged(true, true);
+        }
+    };
 
-        final String filteredPattern = pattern.replaceAll("'.*?'", "");
-
-        final int dayIndex = filteredPattern.indexOf('d');
-        final int monthMIndex = filteredPattern.indexOf("M");
-        final int monthIndex = (monthMIndex != -1) ? monthMIndex : filteredPattern.indexOf("L");
-        final int yearIndex = filteredPattern.indexOf("y");
-
-        if (yearIndex < monthIndex) {
-            result[YEAR_INDEX] = 0;
-
-            if (monthIndex < dayIndex) {
-                result[MONTH_INDEX] = 1;
-                result[DAY_INDEX] = 2;
-            } else {
-                result[MONTH_INDEX] = 2;
-                result[DAY_INDEX] = 1;
+    /**
+     * Listener called when the user selects a year in the year picker view.
+     */
+    private final OnYearSelectedListener mOnYearSelectedListener = new OnYearSelectedListener() {
+        @Override
+        public void onYearChanged(YearPickerView view, int year) {
+            // If the newly selected month / year does not contain the
+            // currently selected day number, change the selected day number
+            // to the last day of the selected month or year.
+            // e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
+            // e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
+            final int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
+            final int month = mCurrentDate.get(Calendar.MONTH);
+            final int daysInMonth = getDaysInMonth(month, year);
+            if (day > daysInMonth) {
+                mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
             }
-        } else {
-            result[YEAR_INDEX] = 2;
 
-            if (monthIndex < dayIndex) {
-                result[MONTH_INDEX] = 0;
-                result[DAY_INDEX] = 1;
-            } else {
-                result[MONTH_INDEX] = 1;
-                result[DAY_INDEX] = 0;
+            mCurrentDate.set(Calendar.YEAR, year);
+            onDateChanged(true, true);
+
+            // Automatically switch to day picker.
+            setCurrentView(VIEW_MONTH_DAY);
+        }
+    };
+
+    /**
+     * Listener called when the user clicks on a header item.
+     */
+    private final OnClickListener mOnHeaderClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            tryVibrate();
+
+            switch (v.getId()) {
+                case R.id.date_picker_header_year:
+                    setCurrentView(VIEW_YEAR);
+                    break;
+                case R.id.date_picker_header_date:
+                    setCurrentView(VIEW_MONTH_DAY);
+                    break;
             }
         }
-        return result;
+    };
+
+    @Override
+    protected void onLocaleChanged(Locale locale) {
+        final TextView headerYear = mHeaderYear;
+        if (headerYear == null) {
+            // Abort, we haven't initialized yet. This method will get called
+            // again later after everything has been set up.
+            return;
+        }
+
+        // Update the date formatter.
+        final String datePattern = DateFormat.getBestDateTimePattern(locale, "EMMMd");
+        mMonthDayFormat = new SimpleDateFormat(datePattern, locale);
+        mYearFormat = new SimpleDateFormat("y", locale);
+
+        // Update the header text.
+        onCurrentDateChanged(false);
     }
 
-    private void updateDisplay(boolean announce) {
-        if (mDayOfWeekView != null) {
-            mDayOfWeekView.setText(mCurrentDate.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
-                    Locale.getDefault()));
+    private void onCurrentDateChanged(boolean announce) {
+        if (mHeaderYear == null) {
+            // Abort, we haven't initialized yet. This method will get called
+            // again later after everything has been set up.
+            return;
         }
 
-        // Compute indices of Month, Day and Year views
-        final String bestDateTimePattern =
-                DateFormat.getBestDateTimePattern(mCurrentLocale, "yMMMd");
-        final int[] viewIndices = getMonthDayYearIndexes(bestDateTimePattern);
+        final String year = mYearFormat.format(mCurrentDate.getTime());
+        mHeaderYear.setText(year);
 
-        // Position the Year and MonthAndDay views within the header.
-        mMonthDayYearLayout.removeAllViews();
-        if (viewIndices[YEAR_INDEX] == 0) {
-            mMonthDayYearLayout.addView(mHeaderYearTextView);
-            mMonthDayYearLayout.addView(mMonthAndDayLayout);
-        } else {
-            mMonthDayYearLayout.addView(mMonthAndDayLayout);
-            mMonthDayYearLayout.addView(mHeaderYearTextView);
-        }
+        final String monthDay = mMonthDayFormat.format(mCurrentDate.getTime());
+        mHeaderMonthDay.setText(monthDay);
 
-        // Position Day and Month views within the MonthAndDay view.
-        mMonthAndDayLayout.removeAllViews();
-        if (viewIndices[MONTH_INDEX] > viewIndices[DAY_INDEX]) {
-            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
-            mMonthAndDayLayout.addView(mHeaderMonthTextView);
-        } else {
-            mMonthAndDayLayout.addView(mHeaderMonthTextView);
-            mMonthAndDayLayout.addView(mHeaderDayOfMonthTextView);
-        }
-
-        mHeaderMonthTextView.setText(mCurrentDate.getDisplayName(Calendar.MONTH, Calendar.SHORT,
-                Locale.getDefault()).toUpperCase(Locale.getDefault()));
-        mHeaderDayOfMonthTextView.setText(mDayFormat.format(mCurrentDate.getTime()));
-        mHeaderYearTextView.setText(mYearFormat.format(mCurrentDate.getTime()));
-
-        // Accessibility.
-        long millis = mCurrentDate.getTimeInMillis();
-        mAnimator.setDateMillis(millis);
-        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
-        String monthAndDayText = DateUtils.formatDateTime(mContext, millis, flags);
-        mMonthAndDayLayout.setContentDescription(monthAndDayText);
-
+        // TODO: This should use live regions.
         if (announce) {
-            flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
-            String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
+            final long millis = mCurrentDate.getTimeInMillis();
+            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
+            final String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
             mAnimator.announceForAccessibility(fullDateText);
         }
     }
 
     private void setCurrentView(final int viewIndex) {
-        long millis = mCurrentDate.getTimeInMillis();
-
         switch (viewIndex) {
-            case MONTH_AND_DAY_VIEW:
-                mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
+            case VIEW_MONTH_DAY:
+                mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
+
                 if (mCurrentView != viewIndex) {
-                    mMonthAndDayLayout.setSelected(true);
-                    mHeaderYearTextView.setSelected(false);
-                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
+                    mHeaderMonthDay.setActivated(true);
+                    mHeaderYear.setActivated(false);
+                    mAnimator.setDisplayedChild(VIEW_MONTH_DAY);
                     mCurrentView = viewIndex;
                 }
 
-                final int flags = DateUtils.FORMAT_SHOW_DATE;
-                final String dayString = DateUtils.formatDateTime(mContext, millis, flags);
-                mAnimator.setContentDescription(mDayPickerDescription + ": " + dayString);
                 mAnimator.announceForAccessibility(mSelectDay);
                 break;
-            case YEAR_VIEW:
-                mYearPickerView.onDateChanged();
+            case VIEW_YEAR:
+                mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
+
                 if (mCurrentView != viewIndex) {
-                    mMonthAndDayLayout.setSelected(false);
-                    mHeaderYearTextView.setSelected(true);
-                    mAnimator.setDisplayedChild(YEAR_VIEW);
+                    mHeaderMonthDay.setActivated(false);
+                    mHeaderYear.setActivated(true);
+                    mAnimator.setDisplayedChild(VIEW_YEAR);
                     mCurrentView = viewIndex;
                 }
 
-                final CharSequence yearString = mYearFormat.format(millis);
-                mAnimator.setContentDescription(mYearPickerDescription + ": " + yearString);
                 mAnimator.announceForAccessibility(mSelectYear);
                 break;
         }
@@ -383,20 +402,18 @@
     }
 
     private void onDateChanged(boolean fromUser, boolean callbackToClient) {
+        final int year = mCurrentDate.get(Calendar.YEAR);
+
         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);
         }
 
-        for (OnDateChangedListener listener : mListeners) {
-            listener.onDateChanged();
-        }
+        mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
+        mYearPickerView.setYear(year);
 
-        mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
-
-        updateDisplay(fromUser);
+        onCurrentDateChanged(fromUser);
 
         if (fromUser) {
             tryVibrate();
@@ -477,15 +494,12 @@
 
     @Override
     public void setEnabled(boolean enabled) {
-        mMonthAndDayLayout.setEnabled(enabled);
-        mHeaderYearTextView.setEnabled(enabled);
-        mAnimator.setEnabled(enabled);
-        mIsEnabled = enabled;
+        mContainer.setEnabled(false);
     }
 
     @Override
     public boolean isEnabled() {
-        return mIsEnabled;
+        return mContainer.isEnabled();
     }
 
     @Override
@@ -516,8 +530,7 @@
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        mYearFormat = new SimpleDateFormat("y", newConfig.locale);
-        mDayFormat = new SimpleDateFormat("d", newConfig.locale);
+        setCurrentLocale(newConfig.locale);
     }
 
     @Override
@@ -529,9 +542,9 @@
         int listPosition = -1;
         int listPositionOffset = -1;
 
-        if (mCurrentView == MONTH_AND_DAY_VIEW) {
+        if (mCurrentView == VIEW_MONTH_DAY) {
             listPosition = mDayPickerView.getMostVisiblePosition();
-        } else if (mCurrentView == YEAR_VIEW) {
+        } else if (mCurrentView == VIEW_YEAR) {
             listPosition = mYearPickerView.getFirstVisiblePosition();
             listPositionOffset = mYearPickerView.getFirstPositionOffset();
         }
@@ -544,20 +557,22 @@
     public void onRestoreInstanceState(Parcelable state) {
         SavedState ss = (SavedState) state;
 
+        // TODO: Move instance state into DayPickerView, YearPickerView.
         mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
         mCurrentView = ss.getCurrentView();
         mMinDate.setTimeInMillis(ss.getMinDate());
         mMaxDate.setTimeInMillis(ss.getMaxDate());
 
-        updateDisplay(false);
+        onCurrentDateChanged(false);
         setCurrentView(mCurrentView);
 
         final int listPosition = ss.getListPosition();
         if (listPosition != -1) {
-            if (mCurrentView == MONTH_AND_DAY_VIEW) {
-                mDayPickerView.postSetSelection(listPosition);
-            } else if (mCurrentView == YEAR_VIEW) {
-                mYearPickerView.postSetSelectionFromTop(listPosition, ss.getListPositionOffset());
+            if (mCurrentView == VIEW_MONTH_DAY) {
+                mDayPickerView.setCurrentItem(listPosition);
+            } else if (mCurrentView == VIEW_YEAR) {
+                final int listPositionOffset = ss.getListPositionOffset();
+                mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset);
             }
         }
     }
@@ -577,28 +592,6 @@
         return DatePicker.class.getName();
     }
 
-    @Override
-    public void onYearSelected(int year) {
-        adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
-        mCurrentDate.set(Calendar.YEAR, year);
-        onDateChanged(true, true);
-
-        // Auto-advance to month and day view.
-        setCurrentView(MONTH_AND_DAY_VIEW);
-    }
-
-    // If the newly selected month / year does not contain the currently selected day number,
-    // change the selected day number to the last day of the selected month or year.
-    //      e.g. Switching from Mar to Apr when Mar 31 is selected -> Apr 30
-    //      e.g. Switching from 2012 to 2013 when Feb 29, 2012 is selected -> Feb 28, 2013
-    private void adjustDayInMonthIfNeeded(int month, int year) {
-        int day = mCurrentDate.get(Calendar.DAY_OF_MONTH);
-        int daysInMonth = getDaysInMonth(month, year);
-        if (day > daysInMonth) {
-            mCurrentDate.set(Calendar.DAY_OF_MONTH, daysInMonth);
-        }
-    }
-
     public static int getDaysInMonth(int month, int year) {
         switch (month) {
             case Calendar.JANUARY:
@@ -621,43 +614,10 @@
         }
     }
 
-    @Override
-    public void registerOnDateChangedListener(OnDateChangedListener listener) {
-        mListeners.add(listener);
-    }
-
-    @Override
-    public Calendar getSelectedDay() {
-        return mCurrentDate;
-    }
-
-    @Override
-    public void tryVibrate() {
+    private void tryVibrate() {
         mDelegator.performHapticFeedback(HapticFeedbackConstants.CALENDAR_DATE);
     }
 
-    @Override
-    public void onClick(View v) {
-        tryVibrate();
-        if (v.getId() == R.id.date_picker_year) {
-            setCurrentView(YEAR_VIEW);
-        } else if (v.getId() == R.id.date_picker_month_and_day_layout) {
-            setCurrentView(MONTH_AND_DAY_VIEW);
-        }
-    }
-
-    /**
-     * Listener called when the user selects a day in the day picker view.
-     */
-    private final DayPickerView.OnDaySelectedListener
-            mOnDaySelectedListener = new DayPickerView.OnDaySelectedListener() {
-        @Override
-        public void onDaySelected(DayPickerView view, Calendar day) {
-            mCurrentDate.setTimeInMillis(day.getTimeInMillis());
-            onDateChanged(true, true);
-        }
-    };
-
     /**
      * Class for managing state storing/restoring.
      */
diff --git a/core/java/android/widget/DayPickerAdapter.java b/core/java/android/widget/DayPickerAdapter.java
new file mode 100644
index 0000000..4f9f09e
--- /dev/null
+++ b/core/java/android/widget/DayPickerAdapter.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2015 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.widget;
+
+import com.android.internal.widget.PagerAdapter;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.SimpleMonthView.OnDayClickListener;
+
+import java.util.Calendar;
+
+/**
+ * An adapter for a list of {@link android.widget.SimpleMonthView} items.
+ */
+class DayPickerAdapter extends PagerAdapter {
+    private static final int MONTHS_IN_YEAR = 12;
+
+    private final Calendar mMinDate = Calendar.getInstance();
+    private final Calendar mMaxDate = Calendar.getInstance();
+
+    private final SparseArray<SimpleMonthView> mItems = new SparseArray<>();
+
+    private Calendar mSelectedDay = Calendar.getInstance();
+
+    private int mMonthTextAppearance;
+    private int mDayOfWeekTextAppearance;
+    private int mDayTextAppearance;
+
+    private ColorStateList mCalendarTextColor;
+    private ColorStateList mDaySelectorColor;
+    private ColorStateList mDayHighlightColor;
+
+    private OnDaySelectedListener mOnDaySelectedListener;
+
+    private int mFirstDayOfWeek;
+
+    public DayPickerAdapter(Context context) {
+        final TypedArray ta = context.obtainStyledAttributes(new int[] {
+                com.android.internal.R.attr.colorControlHighlight});
+        mDayHighlightColor = ta.getColorStateList(0);
+        ta.recycle();
+    }
+
+    public void setRange(Calendar min, Calendar max) {
+        mMinDate.setTimeInMillis(min.getTimeInMillis());
+        mMaxDate.setTimeInMillis(max.getTimeInMillis());
+
+        // Positions are now invalid, clear everything and start over.
+        notifyDataSetChanged();
+    }
+
+    /**
+     * Sets the first day of the week.
+     *
+     * @param weekStart which day the week should start on, valid values are
+     *                  {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY}
+     */
+    public void setFirstDayOfWeek(int weekStart) {
+        mFirstDayOfWeek = weekStart;
+
+        // Update displayed views.
+        final int count = mItems.size();
+        for (int i = 0; i < count; i++) {
+            final SimpleMonthView monthView = mItems.valueAt(i);
+            monthView.setFirstDayOfWeek(weekStart);
+        }
+    }
+
+    public int getFirstDayOfWeek() {
+        return mFirstDayOfWeek;
+    }
+
+    /**
+     * Sets the selected day.
+     *
+     * @param day the selected day
+     */
+    public void setSelectedDay(Calendar day) {
+        final int oldPosition = getPositionForDay(mSelectedDay);
+        final int newPosition = getPositionForDay(day);
+
+        // Clear the old position if necessary.
+        if (oldPosition != newPosition) {
+            final SimpleMonthView oldMonthView = mItems.get(oldPosition, null);
+            if (oldMonthView != null) {
+                oldMonthView.setSelectedDay(-1);
+            }
+        }
+
+        // Set the new position.
+        final SimpleMonthView newMonthView = mItems.get(newPosition, null);
+        if (newMonthView != null) {
+            final int dayOfMonth = day.get(Calendar.DAY_OF_MONTH);
+            newMonthView.setSelectedDay(dayOfMonth);
+        }
+
+        mSelectedDay = day;
+    }
+
+    /**
+     * Sets the listener to call when the user selects a day.
+     *
+     * @param listener The listener to call.
+     */
+    public void setOnDaySelectedListener(OnDaySelectedListener listener) {
+        mOnDaySelectedListener = listener;
+    }
+
+    void setCalendarTextColor(ColorStateList calendarTextColor) {
+        mCalendarTextColor = calendarTextColor;
+    }
+
+    void setDaySelectorColor(ColorStateList selectorColor) {
+        mDaySelectorColor = selectorColor;
+    }
+
+    void setMonthTextAppearance(int resId) {
+        mMonthTextAppearance = resId;
+    }
+
+    void setDayOfWeekTextAppearance(int resId) {
+        mDayOfWeekTextAppearance = resId;
+    }
+
+    int getDayOfWeekTextAppearance() {
+        return mDayOfWeekTextAppearance;
+    }
+
+    void setDayTextAppearance(int resId) {
+        mDayTextAppearance = resId;
+    }
+
+    int getDayTextAppearance() {
+        return mDayTextAppearance;
+    }
+
+    @Override
+    public int getCount() {
+        final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
+        final int diffMonth = mMaxDate.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
+        return diffMonth + MONTHS_IN_YEAR * diffYear + 1;
+    }
+
+    @Override
+    public boolean isViewFromObject(View view, Object object) {
+        return view == object;
+    }
+
+    private int getMonthForPosition(int position) {
+        return position % MONTHS_IN_YEAR + mMinDate.get(Calendar.MONTH);
+    }
+
+    private int getYearForPosition(int position) {
+        return position / MONTHS_IN_YEAR + mMinDate.get(Calendar.YEAR);
+    }
+
+    private int getPositionForDay(Calendar day) {
+        final int yearOffset = (day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR));
+        final int monthOffset = (day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH));
+        return yearOffset * MONTHS_IN_YEAR + monthOffset;
+    }
+
+    @Override
+    public Object instantiateItem(ViewGroup container, int position) {
+        final SimpleMonthView v = new SimpleMonthView(container.getContext());
+        v.setOnDayClickListener(mOnDayClickListener);
+        v.setMonthTextAppearance(mMonthTextAppearance);
+        v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance);
+        v.setDayTextAppearance(mDayTextAppearance);
+
+        if (mDaySelectorColor != null) {
+            v.setDaySelectorColor(mDaySelectorColor);
+        }
+
+        if (mDayHighlightColor != null) {
+            v.setDayHighlightColor(mDayHighlightColor);
+        }
+
+        if (mCalendarTextColor != null) {
+            v.setMonthTextColor(mCalendarTextColor);
+            v.setDayOfWeekTextColor(mCalendarTextColor);
+            v.setDayTextColor(mCalendarTextColor);
+        }
+
+        final int month = getMonthForPosition(position);
+        final int year = getYearForPosition(position);
+
+        final int selectedDay;
+        if (mSelectedDay.get(Calendar.MONTH) == month) {
+            selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH);
+        } else {
+            selectedDay = -1;
+        }
+
+        final int enabledDayRangeStart;
+        if (mMinDate.get(Calendar.MONTH) == month && mMinDate.get(Calendar.YEAR) == year) {
+            enabledDayRangeStart = mMinDate.get(Calendar.DAY_OF_MONTH);
+        } else {
+            enabledDayRangeStart = 1;
+        }
+
+        final int enabledDayRangeEnd;
+        if (mMaxDate.get(Calendar.MONTH) == month && mMaxDate.get(Calendar.YEAR) == year) {
+            enabledDayRangeEnd = mMaxDate.get(Calendar.DAY_OF_MONTH);
+        } else {
+            enabledDayRangeEnd = 31;
+        }
+
+        v.setMonthParams(selectedDay, month, year, mFirstDayOfWeek,
+                enabledDayRangeStart, enabledDayRangeEnd);
+
+        mItems.put(position, v);
+
+        container.addView(v);
+
+        return v;
+    }
+
+    @Override
+    public void destroyItem(ViewGroup container, int position, Object object) {
+        container.removeView(mItems.get(position));
+
+        mItems.remove(position);
+    }
+
+    @Override
+    public int getItemPosition(Object object) {
+        final int index = mItems.indexOfValue((SimpleMonthView) object);
+        if (index < 0) {
+            return mItems.keyAt(index);
+        }
+        return -1;
+    }
+
+    @Override
+    public CharSequence getPageTitle(int position) {
+        final SimpleMonthView v = mItems.get(position);
+        if (v != null) {
+            return v.getTitle();
+        }
+        return null;
+    }
+
+    private boolean isCalendarInRange(Calendar value) {
+        return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
+    }
+
+    private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
+        @Override
+        public void onDayClick(SimpleMonthView view, Calendar day) {
+            if (day != null && isCalendarInRange(day)) {
+                setSelectedDay(day);
+
+                if (mOnDaySelectedListener != null) {
+                    mOnDaySelectedListener.onDaySelected(DayPickerAdapter.this, day);
+                }
+            }
+        }
+    };
+
+    public interface OnDaySelectedListener {
+        public void onDaySelected(DayPickerAdapter view, Calendar day);
+    }
+}
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 65af45d..a7ae926 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -16,87 +16,177 @@
 
 package android.widget;
 
+import com.android.internal.widget.ViewPager;
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
 import android.util.MathUtils;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
 
-import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
 
+import libcore.icu.LocaleData;
+
 /**
  * This displays a list of months in a calendar format with selectable days.
  */
-class DayPickerView extends ListView implements AbsListView.OnScrollListener {
-    private static final String TAG = "DayPickerView";
+class DayPickerView extends ViewPager {
+    private static final int DEFAULT_START_YEAR = 1900;
+    private static final int DEFAULT_END_YEAR = 2100;
 
-    // How long the GoTo fling animation should last
-    private static final int GOTO_SCROLL_DURATION = 250;
+    private final Calendar mSelectedDay = Calendar.getInstance();
+    private final Calendar mMinDate = Calendar.getInstance();
+    private final Calendar mMaxDate = Calendar.getInstance();
 
-    // How long to wait after receiving an onScrollStateChanged notification before acting on it
-    private static final int SCROLL_CHANGE_DELAY = 40;
+    private final DayPickerAdapter mAdapter;
 
-    // so that the top line will be under the separator
-    private static final int LIST_TOP_OFFSET = -1;
-
-    private final SimpleMonthAdapter mAdapter = new SimpleMonthAdapter(getContext());
-
-    private final ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable(this);
-
-    private SimpleDateFormat mYearFormat = new SimpleDateFormat("yyyy", Locale.getDefault());
-
-    // highlighted time
-    private Calendar mSelectedDay = Calendar.getInstance();
-    private Calendar mTempDay = Calendar.getInstance();
-    private Calendar mMinDate = Calendar.getInstance();
-    private Calendar mMaxDate = Calendar.getInstance();
-
+    /** Temporary calendar used for date calculations. */
     private Calendar mTempCalendar;
 
     private OnDaySelectedListener mOnDaySelectedListener;
 
-    // which month should be displayed/highlighted [0-11]
-    private int mCurrentMonthDisplayed;
-    // used for tracking what state listview is in
-    private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-    // used for tracking what state listview is in
-    private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-    private boolean mPerformingScroll;
-
     public DayPickerView(Context context) {
-        super(context);
+        this(context, null);
+    }
+
+    public DayPickerView(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.calendarViewStyle);
+    }
+
+    public DayPickerView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public DayPickerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.CalendarView, defStyleAttr, defStyleRes);
+
+        final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek,
+                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
+
+        final String minDate = a.getString(R.styleable.CalendarView_minDate);
+        final String maxDate = a.getString(R.styleable.CalendarView_maxDate);
+
+        final int monthTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_monthTextAppearance,
+                R.style.TextAppearance_Material_Widget_Calendar_Month);
+        final int dayOfWeekTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_weekDayTextAppearance,
+                R.style.TextAppearance_Material_Widget_Calendar_DayOfWeek);
+        final int dayTextAppearanceResId = a.getResourceId(
+                R.styleable.CalendarView_dateTextAppearance,
+                R.style.TextAppearance_Material_Widget_Calendar_Day);
+
+        final ColorStateList daySelectorColor = a.getColorStateList(
+                R.styleable.CalendarView_daySelectorColor);
+
+        a.recycle();
+
+        // Set up adapter.
+        mAdapter = new DayPickerAdapter(context);
+        mAdapter.setMonthTextAppearance(monthTextAppearanceResId);
+        mAdapter.setDayOfWeekTextAppearance(dayOfWeekTextAppearanceResId);
+        mAdapter.setDayTextAppearance(dayTextAppearanceResId);
+        mAdapter.setDaySelectorColor(daySelectorColor);
 
         setAdapter(mAdapter);
-        setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-        setDrawSelectorOnTop(false);
-        setUpListView();
 
-        goTo(mSelectedDay.getTimeInMillis(), false, false, true);
+        // Set up min and max dates.
+        final Calendar tempDate = Calendar.getInstance();
+        if (!CalendarView.parseDate(minDate, tempDate)) {
+            tempDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
+        }
+        final long minDateMillis = tempDate.getTimeInMillis();
 
-        mAdapter.setOnDaySelectedListener(mProxyOnDaySelectedListener);
+        if (!CalendarView.parseDate(maxDate, tempDate)) {
+            tempDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
+        }
+        final long maxDateMillis = tempDate.getTimeInMillis();
+
+        if (maxDateMillis < minDateMillis) {
+            throw new IllegalArgumentException("maxDate must be >= minDate");
+        }
+
+        final long setDateMillis = MathUtils.constrain(
+                System.currentTimeMillis(), minDateMillis, maxDateMillis);
+
+        setFirstDayOfWeek(firstDayOfWeek);
+        setMinDate(minDateMillis);
+        setMaxDate(maxDateMillis);
+        setDate(setDateMillis, false);
+
+        // Proxy selection callbacks to our own listener.
+        mAdapter.setOnDaySelectedListener(new DayPickerAdapter.OnDaySelectedListener() {
+            @Override
+            public void onDaySelected(DayPickerAdapter adapter, Calendar day) {
+                if (mOnDaySelectedListener != null) {
+                    mOnDaySelectedListener.onDaySelected(DayPickerView.this, day);
+                }
+            }
+        });
+    }
+
+    public void setDayOfWeekTextAppearance(int resId) {
+        mAdapter.setDayOfWeekTextAppearance(resId);
+    }
+
+    public int getDayOfWeekTextAppearance() {
+        return mAdapter.getDayOfWeekTextAppearance();
+    }
+
+    public void setDayTextAppearance(int resId) {
+        mAdapter.setDayTextAppearance(resId);
+    }
+
+    public int getDayTextAppearance() {
+        return mAdapter.getDayTextAppearance();
     }
 
     /**
      * Sets the currently selected date to the specified timestamp. Jumps
      * immediately to the new date. To animate to the new date, use
-     * {@link #setDate(long, boolean, boolean)}.
+     * {@link #setDate(long, boolean)}.
      *
-     * @param timeInMillis
+     * @param timeInMillis the target day in milliseconds
      */
     public void setDate(long timeInMillis) {
-        setDate(timeInMillis, false, true);
+        setDate(timeInMillis, false);
     }
 
-    public void setDate(long timeInMillis, boolean animate, boolean forceScroll) {
-        goTo(timeInMillis, animate, true, forceScroll);
+    /**
+     * Sets the currently selected date to the specified timestamp. Jumps
+     * immediately to the new date, optionally animating the transition.
+     *
+     * @param timeInMillis the target day in milliseconds
+     * @param animate whether to smooth scroll to the new position
+     */
+    public void setDate(long timeInMillis, boolean animate) {
+        setDate(timeInMillis, animate, true);
+    }
+
+    /**
+     * Moves to the month containing the specified day, optionally setting the
+     * day as selected.
+     *
+     * @param timeInMillis the target day in milliseconds
+     * @param animate whether to smooth scroll to the new position
+     * @param setSelected whether to set the specified day as selected
+     */
+    private void setDate(long timeInMillis, boolean animate, boolean setSelected) {
+        // Set the selected day
+        if (setSelected) {
+            mSelectedDay.setTimeInMillis(timeInMillis);
+        }
+
+        final int position = getPositionFromDay(timeInMillis);
+        if (position != getCurrentItem()) {
+            setCurrentItem(position, animate);
+        }
     }
 
     public long getDate() {
@@ -137,7 +227,7 @@
 
         // Changing the min/max date changes the selection position since we
         // don't really have stable IDs. Jumps immediately to the new position.
-        goTo(mSelectedDay.getTimeInMillis(), false, false, true);
+        setDate(mSelectedDay.getTimeInMillis(), false, false);
     }
 
     /**
@@ -149,30 +239,9 @@
         mOnDaySelectedListener = listener;
     }
 
-    /*
-     * Sets all the required fields for the list view. Override this method to
-     * set a different list view behavior.
-     */
-    private void setUpListView() {
-        // Transparent background on scroll
-        setCacheColorHint(0);
-        // No dividers
-        setDivider(null);
-        // Items are clickable
-        setItemsCanFocus(true);
-        // The thumb gets in the way, so disable it
-        setFastScrollEnabled(false);
-        setVerticalScrollBarEnabled(false);
-        setOnScrollListener(this);
-        setFadingEdgeLength(0);
-        // Make the scrolling behavior nicer
-        setFriction(ViewConfiguration.getScrollFriction());
-    }
-
     private int getDiffMonths(Calendar start, Calendar end) {
         final int diffYears = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
-        final int diffMonths = end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears;
-        return diffMonths;
+        return end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears;
     }
 
     private int getPositionFromDay(long timeInMillis) {
@@ -190,366 +259,13 @@
     }
 
     /**
-     * This moves to the specified time in the view. If the time is not already
-     * in range it will move the list so that the first of the month containing
-     * the time is at the top of the view. If the new time is already in view
-     * the list will not be scrolled unless forceScroll is true. This time may
-     * optionally be highlighted as selected as well.
-     *
-     * @param day The day to move to
-     * @param animate Whether to scroll to the given time or just redraw at the
-     *            new location
-     * @param setSelected Whether to set the given time as selected
-     * @param forceScroll Whether to recenter even if the time is already
-     *            visible
-     * @return Whether or not the view animated to the new location
-     */
-    private boolean goTo(long day, boolean animate, boolean setSelected, boolean forceScroll) {
-
-        // Set the selected day
-        if (setSelected) {
-            mSelectedDay.setTimeInMillis(day);
-        }
-
-        mTempDay.setTimeInMillis(day);
-        final int position = getPositionFromDay(day);
-
-        View child;
-        int i = 0;
-        int top = 0;
-        // Find a child that's completely in the view
-        do {
-            child = getChildAt(i++);
-            if (child == null) {
-                break;
-            }
-            top = child.getTop();
-        } while (top < 0);
-
-        // Compute the first and last position visible
-        int selectedPosition;
-        if (child != null) {
-            selectedPosition = getPositionForView(child);
-        } else {
-            selectedPosition = 0;
-        }
-
-        if (setSelected) {
-            mAdapter.setSelectedDay(mSelectedDay);
-        }
-
-        // Check if the selected day is now outside of our visible range
-        // and if so scroll to the month that contains it
-        if (position != selectedPosition || forceScroll) {
-            setMonthDisplayed(mTempDay);
-            mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
-            if (animate) {
-                smoothScrollToPositionFromTop(
-                        position, LIST_TOP_OFFSET, GOTO_SCROLL_DURATION);
-                return true;
-            } else {
-                postSetSelection(position);
-            }
-        } else if (setSelected) {
-            setMonthDisplayed(mSelectedDay);
-        }
-        return false;
-    }
-
-    public void postSetSelection(final int position) {
-        clearFocus();
-        post(new Runnable() {
-
-            @Override
-            public void run() {
-                setSelection(position);
-            }
-        });
-        onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_IDLE);
-    }
-
-    /**
-     * Updates the title and selected month if the view has moved to a new
-     * month.
-     */
-    @Override
-    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
-                         int totalItemCount) {
-        SimpleMonthView child = (SimpleMonthView) view.getChildAt(0);
-        if (child == null) {
-            return;
-        }
-
-        mPreviousScrollState = mCurrentScrollState;
-    }
-
-    /**
-     * Sets the month displayed at the top of this view based on time. Override
-     * to add custom events when the title is changed.
-     */
-    protected void setMonthDisplayed(Calendar date) {
-        if (mCurrentMonthDisplayed != date.get(Calendar.MONTH)) {
-            mCurrentMonthDisplayed = date.get(Calendar.MONTH);
-            invalidateViews();
-        }
-    }
-
-    @Override
-    public void onScrollStateChanged(AbsListView view, int scrollState) {
-        // use a post to prevent re-entering onScrollStateChanged before it
-        // exits
-        mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
-    }
-
-    void setCalendarTextColor(ColorStateList colors) {
-        mAdapter.setCalendarTextColor(colors);
-    }
-
-    void setCalendarDayBackgroundColor(ColorStateList dayBackgroundColor) {
-        mAdapter.setCalendarDayBackgroundColor(dayBackgroundColor);
-    }
-
-    void setCalendarTextAppearance(int resId) {
-        mAdapter.setCalendarTextAppearance(resId);
-    }
-
-    protected class ScrollStateRunnable implements Runnable {
-        private int mNewState;
-        private View mParent;
-
-        ScrollStateRunnable(View view) {
-            mParent = view;
-        }
-
-        /**
-         * Sets up the runnable with a short delay in case the scroll state
-         * immediately changes again.
-         *
-         * @param view The list view that changed state
-         * @param scrollState The new state it changed to
-         */
-        public void doScrollStateChange(AbsListView view, int scrollState) {
-            mParent.removeCallbacks(this);
-            mNewState = scrollState;
-            mParent.postDelayed(this, SCROLL_CHANGE_DELAY);
-        }
-
-        @Override
-        public void run() {
-            mCurrentScrollState = mNewState;
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG,
-                        "new scroll state: " + mNewState + " old state: " + mPreviousScrollState);
-            }
-            // Fix the position after a scroll or a fling ends
-            if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
-                    && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE
-                    && mPreviousScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
-                mPreviousScrollState = mNewState;
-                int i = 0;
-                View child = getChildAt(i);
-                while (child != null && child.getBottom() <= 0) {
-                    child = getChildAt(++i);
-                }
-                if (child == null) {
-                    // The view is no longer visible, just return
-                    return;
-                }
-                int firstPosition = getFirstVisiblePosition();
-                int lastPosition = getLastVisiblePosition();
-                boolean scroll = firstPosition != 0 && lastPosition != getCount() - 1;
-                final int top = child.getTop();
-                final int bottom = child.getBottom();
-                final int midpoint = getHeight() / 2;
-                if (scroll && top < LIST_TOP_OFFSET) {
-                    if (bottom > midpoint) {
-                        smoothScrollBy(top, GOTO_SCROLL_DURATION);
-                    } else {
-                        smoothScrollBy(bottom, GOTO_SCROLL_DURATION);
-                    }
-                }
-            } else {
-                mPreviousScrollState = mNewState;
-            }
-        }
-    }
-
-    /**
      * Gets the position of the view that is most prominently displayed within the list view.
      */
     public int getMostVisiblePosition() {
-        final int firstPosition = getFirstVisiblePosition();
-        final int height = getHeight();
-
-        int maxDisplayedHeight = 0;
-        int mostVisibleIndex = 0;
-        int i=0;
-        int bottom = 0;
-        while (bottom < height) {
-            View child = getChildAt(i);
-            if (child == null) {
-                break;
-            }
-            bottom = child.getBottom();
-            int displayedHeight = Math.min(bottom, height) - Math.max(0, child.getTop());
-            if (displayedHeight > maxDisplayedHeight) {
-                mostVisibleIndex = i;
-                maxDisplayedHeight = displayedHeight;
-            }
-            i++;
-        }
-        return firstPosition + mostVisibleIndex;
-    }
-
-    /**
-     * Attempts to return the date that has accessibility focus.
-     *
-     * @return The date that has accessibility focus, or {@code null} if no date
-     *         has focus.
-     */
-    private Calendar findAccessibilityFocus() {
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-            if (child instanceof SimpleMonthView) {
-                final Calendar focus = ((SimpleMonthView) child).getAccessibilityFocus();
-                if (focus != null) {
-                    return focus;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Attempts to restore accessibility focus to a given date. No-op if
-     * {@code day} is {@code null}.
-     *
-     * @param day The date that should receive accessibility focus
-     * @return {@code true} if focus was restored
-     */
-    private boolean restoreAccessibilityFocus(Calendar day) {
-        if (day == null) {
-            return false;
-        }
-
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-            if (child instanceof SimpleMonthView) {
-                if (((SimpleMonthView) child).restoreAccessibilityFocus(day)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void layoutChildren() {
-        final Calendar focusedDay = findAccessibilityFocus();
-        super.layoutChildren();
-        if (mPerformingScroll) {
-            mPerformingScroll = false;
-        } else {
-            restoreAccessibilityFocus(focusedDay);
-        }
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        mYearFormat = new SimpleDateFormat("yyyy", Locale.getDefault());
-    }
-
-    /** @hide */
-    @Override
-    public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEventInternal(event);
-        event.setItemCount(-1);
-    }
-
-    private String getMonthAndYearString(Calendar day) {
-        final StringBuilder sbuf = new StringBuilder();
-        sbuf.append(day.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
-        sbuf.append(" ");
-        sbuf.append(mYearFormat.format(day.getTime()));
-        return sbuf.toString();
-    }
-
-    /**
-     * Necessary for accessibility, to ensure we support "scrolling" forward and backward
-     * in the month list.
-     *
-     * @hide
-     */
-    @Override
-    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfoInternal(info);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
-    }
-
-    /**
-     * When scroll forward/backward events are received, announce the newly scrolled-to month.
-     *
-     * @hide
-     */
-    @Override
-    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
-        if (action != AccessibilityNodeInfo.ACTION_SCROLL_FORWARD &&
-                action != AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
-            return super.performAccessibilityActionInternal(action, arguments);
-        }
-
-        // Figure out what month is showing.
-        final int firstVisiblePosition = getFirstVisiblePosition();
-        final int month = firstVisiblePosition % 12;
-        final int year = firstVisiblePosition / 12 + mMinDate.get(Calendar.YEAR);
-        final Calendar day = Calendar.getInstance();
-        day.set(year, month, 1);
-
-        // Scroll either forward or backward one month.
-        if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
-            day.add(Calendar.MONTH, 1);
-            if (day.get(Calendar.MONTH) == 12) {
-                day.set(Calendar.MONTH, 0);
-                day.add(Calendar.YEAR, 1);
-            }
-        } else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
-            View firstVisibleView = getChildAt(0);
-            // If the view is fully visible, jump one month back. Otherwise, we'll just jump
-            // to the first day of first visible month.
-            if (firstVisibleView != null && firstVisibleView.getTop() >= -1) {
-                // There's an off-by-one somewhere, so the top of the first visible item will
-                // actually be -1 when it's at the exact top.
-                day.add(Calendar.MONTH, -1);
-                if (day.get(Calendar.MONTH) == -1) {
-                    day.set(Calendar.MONTH, 11);
-                    day.add(Calendar.YEAR, -1);
-                }
-            }
-        }
-
-        // Go to that month.
-        announceForAccessibility(getMonthAndYearString(day));
-        goTo(day.getTimeInMillis(), true, false, true);
-        mPerformingScroll = true;
-        return true;
+        return getCurrentItem();
     }
 
     public interface OnDaySelectedListener {
         public void onDaySelected(DayPickerView view, Calendar day);
     }
-
-    private final SimpleMonthAdapter.OnDaySelectedListener
-            mProxyOnDaySelectedListener = new SimpleMonthAdapter.OnDaySelectedListener() {
-        @Override
-        public void onDaySelected(SimpleMonthAdapter adapter, Calendar day) {
-            if (mOnDaySelectedListener != null) {
-                mOnDaySelectedListener.onDaySelected(DayPickerView.this, day);
-            }
-        }
-    };
 }
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index d85bbb9..310412f9 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -567,13 +567,11 @@
     public void show() {
         int height = buildDropDown();
 
-        int widthSpec = 0;
-        int heightSpec = 0;
-
         boolean noInputMethod = isInputMethodNotNeeded();
         mPopup.setAllowScrollingAnchorParent(!noInputMethod);
 
         if (mPopup.isShowing()) {
+            final int widthSpec;
             if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
                 // The call to PopupWindow's update method below can accept -1 for any
                 // value you do not want to update.
@@ -584,19 +582,19 @@
                 widthSpec = mDropDownWidth;
             }
 
+            final int heightSpec;
             if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
                 // The call to PopupWindow's update method below can accept -1 for any
                 // value you do not want to update.
                 heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT;
                 if (noInputMethod) {
-                    mPopup.setWindowLayoutMode(
-                            mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
-                                    ViewGroup.LayoutParams.MATCH_PARENT : 0, 0);
+                    mPopup.setWidth(mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
+                            ViewGroup.LayoutParams.MATCH_PARENT : 0);
+                    mPopup.setHeight(0);
                 } else {
-                    mPopup.setWindowLayoutMode(
-                            mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
-                                    ViewGroup.LayoutParams.MATCH_PARENT : 0,
-                            ViewGroup.LayoutParams.MATCH_PARENT);
+                    mPopup.setWidth(mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
+                                    ViewGroup.LayoutParams.MATCH_PARENT : 0);
+                    mPopup.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
                 }
             } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
                 heightSpec = height;
@@ -604,32 +602,37 @@
                 heightSpec = mDropDownHeight;
             }
 
+            mPopup.setWidth(widthSpec);
+            mPopup.setHeight(heightSpec);
             mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
 
             mPopup.update(getAnchorView(), mDropDownHorizontalOffset,
-                    mDropDownVerticalOffset, widthSpec, heightSpec);
+                            mDropDownVerticalOffset, -1, -1);
         } else {
+            final int widthSpec;
             if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
                 widthSpec = ViewGroup.LayoutParams.MATCH_PARENT;
             } else {
                 if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
-                    mPopup.setWidth(getAnchorView().getWidth());
+                    widthSpec = getAnchorView().getWidth();
                 } else {
-                    mPopup.setWidth(mDropDownWidth);
+                    widthSpec = mDropDownWidth;
                 }
             }
 
+            final int heightSpec;
             if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
                 heightSpec = ViewGroup.LayoutParams.MATCH_PARENT;
             } else {
                 if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
-                    mPopup.setHeight(height);
+                    heightSpec = height;
                 } else {
-                    mPopup.setHeight(mDropDownHeight);
+                    heightSpec = mDropDownHeight;
                 }
             }
 
-            mPopup.setWindowLayoutMode(widthSpec, heightSpec);
+            mPopup.setWidth(widthSpec);
+            mPopup.setHeight(heightSpec);
             mPopup.setClipToScreenEnabled(true);
             
             // use outside touchable to dismiss drop down when touching outside of it, so
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index f676254..8792323 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -46,6 +46,7 @@
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.ViewTreeObserver.OnScrollChangedListener;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 
 import java.lang.ref.WeakReference;
 
@@ -126,10 +127,10 @@
     private OnTouchListener mTouchInterceptor;
 
     private int mWidthMode;
-    private int mWidth;
+    private int mWidth = LayoutParams.WRAP_CONTENT;
     private int mLastWidth;
     private int mHeightMode;
-    private int mHeight;
+    private int mHeight = LayoutParams.WRAP_CONTENT;
     private int mLastHeight;
 
     private int mPopupWidth;
@@ -907,17 +908,19 @@
      * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
      * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
      * height.
+     *
+     * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}.
      */
+    @Deprecated
     public void setWindowLayoutMode(int widthSpec, int heightSpec) {
         mWidthMode = widthSpec;
         mHeightMode = heightSpec;
     }
 
     /**
-     * <p>Return this popup's height MeasureSpec</p>
+     * Returns the popup's height MeasureSpec.
      *
      * @return the height MeasureSpec of the popup
-     *
      * @see #setHeight(int)
      */
     public int getHeight() {
@@ -925,13 +928,12 @@
     }
 
     /**
-     * <p>Change the popup's height MeasureSpec</p>
-     *
-     * <p>If the popup is showing, calling this method will take effect only
-     * the next time the popup is shown.</p>
+     * Sets the popup's height MeasureSpec.
+     * <p>
+     * If the popup is showing, calling this method will take effect the next
+     * time the popup is shown.
      *
      * @param height the height MeasureSpec of the popup
-     *
      * @see #getHeight()
      * @see #isShowing()
      */
@@ -940,10 +942,9 @@
     }
 
     /**
-     * <p>Return this popup's width MeasureSpec</p>
+     * Returns the popup's width MeasureSpec.
      *
      * @return the width MeasureSpec of the popup
-     *
      * @see #setWidth(int)
      */
     public int getWidth() {
@@ -951,13 +952,12 @@
     }
 
     /**
-     * <p>Change the popup's width MeasureSpec</p>
-     *
-     * <p>If the popup is showing, calling this method will take effect only
-     * the next time the popup is shown.</p>
+     * Sets the popup's width MeasureSpec.
+     * <p>
+     * If the popup is showing, calling this method will take effect the next
+     * time the popup is shown.
      *
      * @param width the width MeasureSpec of the popup
-     *
      * @see #getWidth()
      * @see #isShowing()
      */
@@ -1658,10 +1658,17 @@
 
     /**
      * Updates the state of the popup window, if it is currently being displayed,
-     * from the currently set state.  This includes:
-     * {@link #setClippingEnabled(boolean)}, {@link #setFocusable(boolean)},
-     * {@link #setIgnoreCheekPress()}, {@link #setInputMethodMode(int)},
-     * {@link #setTouchable(boolean)}, and {@link #setAnimationStyle(int)}.
+     * from the currently set state.
+     * <p>
+     * This includes:
+     * <ul>
+     *     <li>{@link #setClippingEnabled(boolean)}</li>
+     *     <li>{@link #setFocusable(boolean)}</li>
+     *     <li>{@link #setIgnoreCheekPress()}</li>
+     *     <li>{@link #setInputMethodMode(int)}</li>
+     *     <li>{@link #setTouchable(boolean)}</li>
+     *     <li>{@link #setAnimationStyle(int)}</li>
+     * </ul>
      */
     public void update() {
         if (!isShowing() || mContentView == null) {
@@ -1692,12 +1699,13 @@
     }
 
     /**
-     * <p>Updates the dimension of the popup window. Calling this function
-     * also updates the window with the current popup state as described
-     * for {@link #update()}.</p>
+     * Updates the dimension of the popup window.
+     * <p>
+     * Calling this function also updates the window with the current popup
+     * state as described for {@link #update()}.
      *
-     * @param width the new width
-     * @param height the new height
+     * @param width the new width, must be >= 0 or -1 to ignore
+     * @param height the new height, must be >= 0 or -1 to ignore
      */
     public void update(int width, int height) {
         final WindowManager.LayoutParams p =
@@ -1706,40 +1714,43 @@
     }
 
     /**
-     * <p>Updates the position and the dimension of the popup window. Width and
-     * height can be set to -1 to update location only.  Calling this function
-     * also updates the window with the current popup state as
-     * described for {@link #update()}.</p>
+     * Updates the position and the dimension of the popup window.
+     * <p>
+     * Width and height can be set to -1 to update location only. Calling this
+     * function also updates the window with the current popup state as
+     * described for {@link #update()}.
      *
      * @param x the new x location
      * @param y the new y location
-     * @param width the new width, can be -1 to ignore
-     * @param height the new height, can be -1 to ignore
+     * @param width the new width, must be >= 0 or -1 to ignore
+     * @param height the new height, must be >= 0 or -1 to ignore
      */
     public void update(int x, int y, int width, int height) {
         update(x, y, width, height, false);
     }
 
     /**
-     * <p>Updates the position and the dimension of the popup window. Width and
-     * height can be set to -1 to update location only.  Calling this function
-     * also updates the window with the current popup state as
-     * described for {@link #update()}.</p>
+     * Updates the position and the dimension of the popup window.
+     * <p>
+     * Width and height can be set to -1 to update location only. Calling this
+     * function also updates the window with the current popup state as
+     * described for {@link #update()}.
      *
      * @param x the new x location
      * @param y the new y location
-     * @param width the new width, can be -1 to ignore
-     * @param height the new height, can be -1 to ignore
-     * @param force reposition the window even if the specified position
-     *              already seems to correspond to the LayoutParams
+     * @param width the new width, must be >= 0 or -1 to ignore
+     * @param height the new height, must be >= 0 or -1 to ignore
+     * @param force {@code true} to reposition the window even if the specified
+     *              position already seems to correspond to the LayoutParams,
+     *              {@code false} to only reposition if needed
      */
     public void update(int x, int y, int width, int height, boolean force) {
-        if (width != -1) {
+        if (width >= 0) {
             mLastWidth = width;
             setWidth(width);
         }
 
-        if (height != -1) {
+        if (height >= 0) {
             mLastHeight = height;
             setHeight(height);
         }
@@ -1794,32 +1805,34 @@
     }
 
     /**
-     * <p>Updates the position and the dimension of the popup window. Calling this
-     * function also updates the window with the current popup state as described
-     * for {@link #update()}.</p>
+     * Updates the position and the dimension of the popup window.
+     * <p>
+     * Calling this function also updates the window with the current popup
+     * state as described for {@link #update()}.
      *
      * @param anchor the popup's anchor view
-     * @param width the new width, can be -1 to ignore
-     * @param height the new height, can be -1 to ignore
+     * @param width the new width, must be >= 0 or -1 to ignore
+     * @param height the new height, must be >= 0 or -1 to ignore
      */
     public void update(View anchor, int width, int height) {
         update(anchor, false, 0, 0, true, width, height);
     }
 
     /**
-     * <p>Updates the position and the dimension of the popup window. Width and
-     * height can be set to -1 to update location only.  Calling this function
-     * also updates the window with the current popup state as
-     * described for {@link #update()}.</p>
-     *
-     * <p>If the view later scrolls to move <code>anchor</code> to a different
-     * location, the popup will be moved correspondingly.</p>
+     * Updates the position and the dimension of the popup window.
+     * <p>
+     * Width and height can be set to -1 to update location only. Calling this
+     * function also updates the window with the current popup state as
+     * described for {@link #update()}.
+     * <p>
+     * If the view later scrolls to move {@code anchor} to a different
+     * location, the popup will be moved correspondingly.
      *
      * @param anchor the popup's anchor view
      * @param xoff x offset from the view's left edge
      * @param yoff y offset from the view's bottom edge
-     * @param width the new width, can be -1 to ignore
-     * @param height the new height, can be -1 to ignore
+     * @param width the new width, must be >= 0 or -1 to ignore
+     * @param height the new height, must be >= 0 or -1 to ignore
      */
     public void update(View anchor, int xoff, int yoff, int width, int height) {
         update(anchor, true, xoff, yoff, true, width, height);
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
index 28b4db2..20aa972 100644
--- a/core/java/android/widget/RadialTimePickerView.java
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -641,7 +641,7 @@
         mCircleRadius = Math.min(mXCenter, mYCenter);
 
         mMinHypotenuseForInnerNumber = mCircleRadius - mTextInset[HOURS_INNER] - mSelectorRadius;
-        mMaxHypotenuseForOuterNumber = mCircleRadius - mTextInset[HOURS] - mSelectorRadius;
+        mMaxHypotenuseForOuterNumber = mCircleRadius - mTextInset[HOURS] + mSelectorRadius;
         mHalfwayHypotenusePoint = mCircleRadius - (mTextInset[HOURS] + mTextInset[HOURS_INNER]) / 2;
 
         calculatePositionsHours();
@@ -1144,30 +1144,31 @@
 
         private void adjustPicker(int step) {
             final int stepSize;
-            final int initialValue;
+            final int initialStep;
             final int maxValue;
             final int minValue;
             if (mShowHours) {
-                stepSize = DEGREES_FOR_ONE_HOUR;
-                initialValue = getCurrentHour() % 12;
+                stepSize = 1;
 
+                final int currentHour24 = getCurrentHour();
                 if (mIs24HourMode) {
-                    maxValue = 23;
+                    initialStep = currentHour24;
                     minValue = 0;
+                    maxValue = 23;
                 } else {
-                    maxValue = 12;
+                    initialStep = hour24To12(currentHour24);
                     minValue = 1;
+                    maxValue = 12;
                 }
             } else {
-                stepSize = DEGREES_FOR_ONE_MINUTE;
-                initialValue = getCurrentMinute();
-
-                maxValue = 55;
+                stepSize = 5;
+                initialStep = getCurrentMinute() / stepSize;
                 minValue = 0;
+                maxValue = 55;
             }
 
-            final int steppedValue = snapOnly30s(initialValue * stepSize, step) / stepSize;
-            final int clampedValue = MathUtils.constrain(steppedValue, minValue, maxValue);
+            final int nextValue = (initialStep + step) * stepSize;
+            final int clampedValue = MathUtils.constrain(nextValue, minValue, maxValue);
             if (mShowHours) {
                 setCurrentHour(clampedValue);
             } else {
diff --git a/core/java/android/widget/SimpleMonthAdapter.java b/core/java/android/widget/SimpleMonthAdapter.java
deleted file mode 100644
index c807d56..0000000
--- a/core/java/android/widget/SimpleMonthAdapter.java
+++ /dev/null
@@ -1,220 +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.
- */
-
-package android.widget;
-
-import com.android.internal.R;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.SimpleMonthView.OnDayClickListener;
-
-import java.util.Calendar;
-
-/**
- * An adapter for a list of {@link android.widget.SimpleMonthView} items.
- */
-class SimpleMonthAdapter extends BaseAdapter {
-    private final Calendar mMinDate = Calendar.getInstance();
-    private final Calendar mMaxDate = Calendar.getInstance();
-
-    private final Context mContext;
-
-    private Calendar mSelectedDay = Calendar.getInstance();
-    private ColorStateList mCalendarTextColors = ColorStateList.valueOf(Color.BLACK);
-    private ColorStateList mCalendarDayBackgroundColor = ColorStateList.valueOf(Color.MAGENTA);
-    private OnDaySelectedListener mOnDaySelectedListener;
-
-    private int mFirstDayOfWeek;
-
-    public SimpleMonthAdapter(Context context) {
-        mContext = context;
-    }
-
-    public void setRange(Calendar min, Calendar max) {
-        mMinDate.setTimeInMillis(min.getTimeInMillis());
-        mMaxDate.setTimeInMillis(max.getTimeInMillis());
-
-        notifyDataSetInvalidated();
-    }
-
-    public void setFirstDayOfWeek(int firstDayOfWeek) {
-        mFirstDayOfWeek = firstDayOfWeek;
-
-        notifyDataSetInvalidated();
-    }
-
-    public int getFirstDayOfWeek() {
-        return mFirstDayOfWeek;
-    }
-
-    /**
-     * Updates the selected day and related parameters.
-     *
-     * @param day The day to highlight
-     */
-    public void setSelectedDay(Calendar day) {
-        mSelectedDay = day;
-
-        notifyDataSetChanged();
-    }
-
-    /**
-     * Sets the listener to call when the user selects a day.
-     *
-     * @param listener The listener to call.
-     */
-    public void setOnDaySelectedListener(OnDaySelectedListener listener) {
-        mOnDaySelectedListener = listener;
-    }
-
-    void setCalendarTextColor(ColorStateList colors) {
-        mCalendarTextColors = colors;
-    }
-
-    void setCalendarDayBackgroundColor(ColorStateList dayBackgroundColor) {
-        mCalendarDayBackgroundColor = dayBackgroundColor;
-    }
-
-    /**
-     * Sets the text color, size, style, hint color, and highlight color from
-     * the specified TextAppearance resource. This is mostly copied from
-     * {@link TextView#setTextAppearance(Context, int)}.
-     */
-    void setCalendarTextAppearance(int resId) {
-        final TypedArray a = mContext.obtainStyledAttributes(resId, R.styleable.TextAppearance);
-
-        final ColorStateList textColor = a.getColorStateList(R.styleable.TextAppearance_textColor);
-        if (textColor != null) {
-            mCalendarTextColors = textColor;
-        }
-
-        // TODO: Support font size, etc.
-
-        a.recycle();
-    }
-
-    @Override
-    public int getCount() {
-        final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
-        final int diffMonth = mMaxDate.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
-        return diffMonth + 12 * diffYear + 1;
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return null;
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        final SimpleMonthView v;
-        if (convertView != null) {
-            v = (SimpleMonthView) convertView;
-        } else {
-            v = new SimpleMonthView(mContext);
-
-            // Set up the new view
-            final AbsListView.LayoutParams params = new AbsListView.LayoutParams(
-                    AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT);
-            v.setLayoutParams(params);
-            v.setClickable(true);
-            v.setOnDayClickListener(mOnDayClickListener);
-
-            v.setMonthTextColor(mCalendarTextColors);
-            v.setDayOfWeekTextColor(mCalendarTextColors);
-            v.setDayTextColor(mCalendarTextColors);
-
-            v.setDayBackgroundColor(mCalendarDayBackgroundColor);
-        }
-
-        final int minMonth = mMinDate.get(Calendar.MONTH);
-        final int minYear = mMinDate.get(Calendar.YEAR);
-        final int currentMonth = position + minMonth;
-        final int month = currentMonth % 12;
-        final int year = currentMonth / 12 + minYear;
-        final int selectedDay;
-        if (isSelectedDayInMonth(year, month)) {
-            selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH);
-        } else {
-            selectedDay = -1;
-        }
-
-        // Invokes requestLayout() to ensure that the recycled view is set with the appropriate
-        // height/number of weeks before being displayed.
-        v.reuse();
-
-        final int enabledDayRangeStart;
-        if (minMonth == month && minYear == year) {
-            enabledDayRangeStart = mMinDate.get(Calendar.DAY_OF_MONTH);
-        } else {
-            enabledDayRangeStart = 1;
-        }
-
-        final int enabledDayRangeEnd;
-        if (mMaxDate.get(Calendar.MONTH) == month && mMaxDate.get(Calendar.YEAR) == year) {
-            enabledDayRangeEnd = mMaxDate.get(Calendar.DAY_OF_MONTH);
-        } else {
-            enabledDayRangeEnd = 31;
-        }
-
-        v.setMonthParams(selectedDay, month, year, mFirstDayOfWeek,
-                enabledDayRangeStart, enabledDayRangeEnd);
-        v.invalidate();
-
-        return v;
-    }
-
-    private boolean isSelectedDayInMonth(int year, int month) {
-        return mSelectedDay.get(Calendar.YEAR) == year && mSelectedDay.get(Calendar.MONTH) == month;
-    }
-
-    private boolean isCalendarInRange(Calendar value) {
-        return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
-    }
-
-    private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
-        @Override
-        public void onDayClick(SimpleMonthView view, Calendar day) {
-            if (day != null && isCalendarInRange(day)) {
-                setSelectedDay(day);
-
-                if (mOnDaySelectedListener != null) {
-                    mOnDaySelectedListener.onDaySelected(SimpleMonthAdapter.this, day);
-                }
-            }
-        }
-    };
-
-    public interface OnDaySelectedListener {
-        public void onDaySelected(SimpleMonthAdapter view, Calendar day);
-    }
-}
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 58ad515..4e5a39a 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -18,8 +18,8 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Paint.Align;
@@ -29,8 +29,6 @@
 import android.os.Bundle;
 import android.text.TextPaint;
 import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.AttributeSet;
 import android.util.IntArray;
 import android.util.StateSet;
@@ -38,13 +36,13 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import com.android.internal.R;
 import com.android.internal.widget.ExploreByTouchHelper;
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.Formatter;
 import java.util.Locale;
 
 /**
@@ -52,93 +50,80 @@
  * within the specified month.
  */
 class SimpleMonthView extends View {
-    private static final int MIN_ROW_HEIGHT = 10;
+    private static final int DAYS_IN_WEEK = 7;
+    private static final int MAX_WEEKS_IN_MONTH = 6;
 
     private static final int DEFAULT_SELECTED_DAY = -1;
     private static final int DEFAULT_WEEK_START = Calendar.SUNDAY;
-    private static final int DEFAULT_NUM_DAYS = 7;
-    private static final int DEFAULT_NUM_ROWS = 6;
-    private static final int MAX_NUM_ROWS = 6;
 
-    private final Formatter mFormatter;
-    private final StringBuilder mStringBuilder;
-
-    private final int mMonthTextSize;
-    private final int mDayOfWeekTextSize;
-    private final int mDayTextSize;
-
-    /** Height of the header containing the month and day of week labels. */
-    private final int mMonthHeaderHeight;
+    private static final String DEFAULT_TITLE_FORMAT = "MMMMy";
+    private static final String DAY_OF_WEEK_FORMAT = "EEEEE";
 
     private final TextPaint mMonthPaint = new TextPaint();
     private final TextPaint mDayOfWeekPaint = new TextPaint();
     private final TextPaint mDayPaint = new TextPaint();
-
-    private final Paint mDayBackgroundPaint = new Paint();
-
-    /** Single-letter (when available) formatter for the day of week label. */
-    private SimpleDateFormat mDayFormatter = new SimpleDateFormat("EEEEE", Locale.getDefault());
-
-    // affects the padding on the sides of this view
-    private int mPadding = 0;
-
-    private String mDayOfWeekTypeface;
-    private String mMonthTypeface;
-
-    private int mMonth;
-    private int mYear;
-
-    // Quick reference to the width of this view, matches parent
-    private int mWidth;
-
-    // The height this view should draw at in pixels, set by height param
-    private final int mRowHeight;
-
-    // If this view contains the today
-    private boolean mHasToday = false;
-
-    // Which day is selected [0-6] or -1 if no day is selected
-    private int mActivatedDay = -1;
-
-    // Which day is today [0-6] or -1 if no day is today
-    private int mToday = DEFAULT_SELECTED_DAY;
-
-    // Which day of the week to start on [0-6]
-    private int mWeekStart = DEFAULT_WEEK_START;
-
-    // How many days to display
-    private int mNumDays = DEFAULT_NUM_DAYS;
-
-    // The number of days + a spot for week number if it is displayed
-    private int mNumCells = mNumDays;
-
-    private int mDayOfWeekStart = 0;
-
-    // First enabled day
-    private int mEnabledDayStart = 1;
-
-    // Last enabled day
-    private int mEnabledDayEnd = 31;
+    private final Paint mDaySelectorPaint = new Paint();
+    private final Paint mDayHighlightPaint = new Paint();
 
     private final Calendar mCalendar = Calendar.getInstance();
     private final Calendar mDayLabelCalendar = Calendar.getInstance();
 
     private final MonthViewTouchHelper mTouchHelper;
 
-    private int mNumRows = DEFAULT_NUM_ROWS;
+    private final SimpleDateFormat mTitleFormatter;
+    private final SimpleDateFormat mDayOfWeekFormatter;
 
-    // Optional listener for handling day click actions
+    private CharSequence mTitle;
+
+    private int mMonth;
+    private int mYear;
+
+    private int mPaddedWidth;
+    private int mPaddedHeight;
+
+    private final int mMonthHeight;
+    private final int mDayOfWeekHeight;
+    private final int mDayHeight;
+    private final int mCellWidth;
+    private final int mDaySelectorRadius;
+
+    /** The day of month for the selected day, or -1 if no day is selected. */
+    private int mActivatedDay = -1;
+
+    /**
+     * The day of month for today, or -1 if the today is not in the current
+     * month.
+     */
+    private int mToday = DEFAULT_SELECTED_DAY;
+
+    /** The first day of the week (ex. Calendar.SUNDAY). */
+    private int mWeekStart = DEFAULT_WEEK_START;
+
+    /** The number of days (ex. 28) in the current month. */
+    private int mDaysInMonth;
+
+    /**
+     * The day of week (ex. Calendar.SUNDAY) for the first day of the current
+     * month.
+     */
+    private int mDayOfWeekStart;
+
+    /** The day of month for the first (inclusive) enabled day. */
+    private int mEnabledDayStart = 1;
+
+    /** The day of month for the last (inclusive) enabled day. */
+    private int mEnabledDayEnd = 31;
+
+    /** The number of week rows needed to display the current month. */
+    private int mNumWeeks = MAX_WEEKS_IN_MONTH;
+
+    /** Optional listener for handling day click actions. */
     private OnDayClickListener mOnDayClickListener;
 
-    // Whether to prevent setting the accessibility delegate
-    private boolean mLockAccessibilityDelegate;
-
-    private int mNormalTextColor;
-    private int mDisabledTextColor;
-    private int mSelectedDayColor;
-
     private ColorStateList mDayTextColor;
 
+    private int mTouchedDay = -1;
+
     public SimpleMonthView(Context context) {
         this(context, null);
     }
@@ -155,64 +140,123 @@
         super(context, attrs, defStyleAttr, defStyleRes);
 
         final Resources res = context.getResources();
-        mDayOfWeekTypeface = res.getString(R.string.day_of_week_label_typeface);
-        mMonthTypeface = res.getString(R.string.sans_serif);
-
-        mStringBuilder = new StringBuilder(50);
-        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
-
-        mDayTextSize = res.getDimensionPixelSize(R.dimen.datepicker_day_number_size);
-        mMonthTextSize = res.getDimensionPixelSize(R.dimen.datepicker_month_label_size);
-        mDayOfWeekTextSize = res.getDimensionPixelSize(
-                R.dimen.datepicker_month_day_label_text_size);
-        mMonthHeaderHeight = res.getDimensionPixelOffset(
-                R.dimen.datepicker_month_list_item_header_height);
-
-        mRowHeight = Math.max(MIN_ROW_HEIGHT,
-                (res.getDimensionPixelOffset(R.dimen.datepicker_view_animator_height)
-                        - mMonthHeaderHeight) / MAX_NUM_ROWS);
+        mMonthHeight = res.getDimensionPixelSize(R.dimen.date_picker_month_height);
+        mDayOfWeekHeight = res.getDimensionPixelSize(R.dimen.date_picker_day_of_week_height);
+        mDayHeight = res.getDimensionPixelSize(R.dimen.date_picker_day_height);
+        mCellWidth = res.getDimensionPixelSize(R.dimen.date_picker_day_width);
+        mDaySelectorRadius = res.getDimensionPixelSize(R.dimen.date_picker_day_selector_radius);
 
         // Set up accessibility components.
         mTouchHelper = new MonthViewTouchHelper(this);
         setAccessibilityDelegate(mTouchHelper);
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
-        mLockAccessibilityDelegate = true;
 
-        initPaints();
+        final Locale locale = res.getConfiguration().locale;
+        final String titleFormat = DateFormat.getBestDateTimePattern(locale, DEFAULT_TITLE_FORMAT);
+        mTitleFormatter = new SimpleDateFormat(titleFormat, locale);
+        mDayOfWeekFormatter = new SimpleDateFormat(DAY_OF_WEEK_FORMAT, locale);
+
+        setClickable(true);
+        initPaints(res);
+    }
+
+    /**
+     * Applies the specified text appearance resource to a paint, returning the
+     * text color if one is set in the text appearance.
+     *
+     * @param p the paint to modify
+     * @param resId the resource ID of the text appearance
+     * @return the text color, if available
+     */
+    private ColorStateList applyTextAppearance(Paint p, int resId) {
+        final TypedArray ta = mContext.obtainStyledAttributes(null,
+                R.styleable.TextAppearance, 0, resId);
+
+        final String fontFamily = ta.getString(R.styleable.TextAppearance_fontFamily);
+        if (fontFamily != null) {
+            p.setTypeface(Typeface.create(fontFamily, 0));
+        }
+
+        p.setTextSize(ta.getDimensionPixelSize(
+                R.styleable.TextAppearance_textSize, (int) p.getTextSize()));
+
+        final ColorStateList textColor = ta.getColorStateList(R.styleable.TextAppearance_textColor);
+        if (textColor != null) {
+            final int enabledColor = textColor.getColorForState(ENABLED_STATE_SET, 0);
+            p.setColor(enabledColor);
+        }
+
+        ta.recycle();
+
+        return textColor;
+    }
+
+    public void setMonthTextAppearance(int resId) {
+        applyTextAppearance(mMonthPaint, resId);
+        invalidate();
+    }
+
+    public void setDayOfWeekTextAppearance(int resId) {
+        applyTextAppearance(mDayOfWeekPaint, resId);
+        invalidate();
+    }
+
+    public void setDayTextAppearance(int resId) {
+        final ColorStateList textColor = applyTextAppearance(mDayPaint, resId);
+        if (textColor != null) {
+            mDayTextColor = textColor;
+        }
+
+        invalidate();
+    }
+
+    public CharSequence getTitle() {
+        if (mTitle == null) {
+            mTitle = mTitleFormatter.format(mCalendar.getTime());
+        }
+        return mTitle;
     }
 
     /**
      * Sets up the text and style properties for painting.
      */
-    private void initPaints() {
+    private void initPaints(Resources res) {
+        final String monthTypeface = res.getString(R.string.date_picker_month_typeface);
+        final String dayOfWeekTypeface = res.getString(R.string.date_picker_day_of_week_typeface);
+        final String dayTypeface = res.getString(R.string.date_picker_day_typeface);
+
+        final int monthTextSize = res.getDimensionPixelSize(
+                R.dimen.date_picker_month_text_size);
+        final int dayOfWeekTextSize = res.getDimensionPixelSize(
+                R.dimen.date_picker_day_of_week_text_size);
+        final int dayTextSize = res.getDimensionPixelSize(
+                R.dimen.date_picker_day_text_size);
+
         mMonthPaint.setAntiAlias(true);
-        mMonthPaint.setTextSize(mMonthTextSize);
-        mMonthPaint.setTypeface(Typeface.create(mMonthTypeface, Typeface.BOLD));
+        mMonthPaint.setTextSize(monthTextSize);
+        mMonthPaint.setTypeface(Typeface.create(monthTypeface, 0));
         mMonthPaint.setTextAlign(Align.CENTER);
         mMonthPaint.setStyle(Style.FILL);
 
         mDayOfWeekPaint.setAntiAlias(true);
-        mDayOfWeekPaint.setTextSize(mDayOfWeekTextSize);
-        mDayOfWeekPaint.setTypeface(Typeface.create(mDayOfWeekTypeface, Typeface.BOLD));
+        mDayOfWeekPaint.setTextSize(dayOfWeekTextSize);
+        mDayOfWeekPaint.setTypeface(Typeface.create(dayOfWeekTypeface, 0));
         mDayOfWeekPaint.setTextAlign(Align.CENTER);
         mDayOfWeekPaint.setStyle(Style.FILL);
 
-        mDayBackgroundPaint.setAntiAlias(true);
-        mDayBackgroundPaint.setStyle(Style.FILL);
+        mDaySelectorPaint.setAntiAlias(true);
+        mDaySelectorPaint.setStyle(Style.FILL);
+
+        mDayHighlightPaint.setAntiAlias(true);
+        mDayHighlightPaint.setStyle(Style.FILL);
 
         mDayPaint.setAntiAlias(true);
-        mDayPaint.setTextSize(mDayTextSize);
+        mDayPaint.setTextSize(dayTextSize);
+        mDayPaint.setTypeface(Typeface.create(dayTypeface, 0));
         mDayPaint.setTextAlign(Align.CENTER);
         mDayPaint.setStyle(Style.FILL);
     }
 
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        mDayFormatter = new SimpleDateFormat("EEEEE", newConfig.locale);
-    }
-
     void setMonthTextColor(ColorStateList monthTextColor) {
         final int enabledColor = monthTextColor.getColorForState(ENABLED_STATE_SET, 0);
         mMonthPaint.setColor(enabledColor);
@@ -230,20 +274,18 @@
         invalidate();
     }
 
-    void setDayBackgroundColor(ColorStateList dayBackgroundColor) {
+    void setDaySelectorColor(ColorStateList dayBackgroundColor) {
         final int activatedColor = dayBackgroundColor.getColorForState(
                 StateSet.get(StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED), 0);
-        mDayBackgroundPaint.setColor(activatedColor);
+        mDaySelectorPaint.setColor(activatedColor);
         invalidate();
     }
 
-    @Override
-    public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
-        // Workaround for a JB MR1 issue where accessibility delegates on
-        // top-level ListView items are overwritten.
-        if (!mLockAccessibilityDelegate) {
-            super.setAccessibilityDelegate(delegate);
-        }
+    void setDayHighlightColor(ColorStateList dayHighlightColor) {
+        final int pressedColor = dayHighlightColor.getColorForState(
+                StateSet.get(StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED), 0);
+        mDayHighlightPaint.setColor(pressedColor);
+        invalidate();
     }
 
     public void setOnDayClickListener(OnDayClickListener listener) {
@@ -253,30 +295,124 @@
     @Override
     public boolean dispatchHoverEvent(MotionEvent event) {
         // First right-of-refusal goes the touch exploration helper.
-        if (mTouchHelper.dispatchHoverEvent(event)) {
-            return true;
-        }
-        return super.dispatchHoverEvent(event);
+        return mTouchHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         switch (event.getAction()) {
-            case MotionEvent.ACTION_UP:
-                final int day = getDayFromLocation(event.getX(), event.getY());
-                if (day >= 0) {
-                    onDayClick(day);
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                final int touchedDay = getDayAtLocation(event.getX(), event.getY());
+                if (mTouchedDay != touchedDay) {
+                    mTouchedDay = touchedDay;
+                    invalidate();
                 }
                 break;
+
+            case MotionEvent.ACTION_UP:
+                final int clickedDay = getDayAtLocation(event.getX(), event.getY());
+                onDayClicked(clickedDay);
+                // Fall through.
+            case MotionEvent.ACTION_CANCEL:
+                // Reset touched day on stream end.
+                mTouchedDay = -1;
+                invalidate();
+                break;
         }
         return true;
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
-        drawMonthTitle(canvas);
-        drawWeekDayLabels(canvas);
+        final int paddingLeft = getPaddingLeft();
+        final int paddingTop = getPaddingTop();
+        canvas.translate(paddingLeft, paddingTop);
+
+        drawMonth(canvas);
+        drawDaysOfWeek(canvas);
         drawDays(canvas);
+
+        canvas.translate(-paddingLeft, -paddingTop);
+    }
+
+    private void drawMonth(Canvas canvas) {
+        final float x = mPaddedWidth / 2f;
+
+        // Vertically centered within the month header height.
+        final float lineHeight = mMonthPaint.ascent() + mMonthPaint.descent();
+        final float y = (mMonthHeight - lineHeight) / 2f;
+
+        canvas.drawText(getTitle().toString(), x, y, mMonthPaint);
+    }
+
+    private void drawDaysOfWeek(Canvas canvas) {
+        final float cellWidthHalf = mPaddedWidth / (DAYS_IN_WEEK * 2);
+
+        // Vertically centered within the cell height.
+        final float lineHeight = mDayOfWeekPaint.ascent() + mDayOfWeekPaint.descent();
+        final float y = mMonthHeight + (mDayOfWeekHeight - lineHeight) / 2f;
+
+        for (int i = 0; i < DAYS_IN_WEEK; i++) {
+            final int calendarDay = (i + mWeekStart) % DAYS_IN_WEEK;
+            mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay);
+
+            final String dayLabel = mDayOfWeekFormatter.format(mDayLabelCalendar.getTime());
+            final float x = (2 * i + 1) * cellWidthHalf;
+            canvas.drawText(dayLabel, x, y, mDayOfWeekPaint);
+        }
+    }
+
+    /**
+     * Draws the month days.
+     */
+    private void drawDays(Canvas canvas) {
+        final int cellWidthHalf = mPaddedWidth / (DAYS_IN_WEEK * 2);
+
+        // Vertically centered within the cell height.
+        final float halfLineHeight = (mDayPaint.ascent() + mDayPaint.descent()) / 2;
+        float centerY = mMonthHeight + mDayOfWeekHeight + mDayHeight / 2f;
+
+        for (int day = 1, j = findDayOffset(); day <= mDaysInMonth; day++) {
+            final int x = (2 * j + 1) * cellWidthHalf;
+            int stateMask = 0;
+
+            if (day >= mEnabledDayStart && day <= mEnabledDayEnd) {
+                stateMask |= StateSet.VIEW_STATE_ENABLED;
+            }
+
+            final boolean isDayActivated = mActivatedDay == day;
+            if (isDayActivated) {
+                stateMask |= StateSet.VIEW_STATE_ACTIVATED;
+
+                // Adjust the circle to be centered on the row.
+                canvas.drawCircle(x, centerY, mDaySelectorRadius, mDaySelectorPaint);
+            } else if (mTouchedDay == day) {
+                stateMask |= StateSet.VIEW_STATE_PRESSED;
+
+                // Adjust the circle to be centered on the row.
+                canvas.drawCircle(x, centerY, mDaySelectorRadius, mDayHighlightPaint);
+            }
+
+            final boolean isDayToday = mToday == day;
+            final int dayTextColor;
+            if (isDayToday && !isDayActivated) {
+                dayTextColor = mDaySelectorPaint.getColor();
+            } else {
+                final int[] stateSet = StateSet.get(stateMask);
+                dayTextColor = mDayTextColor.getColorForState(stateSet, 0);
+            }
+            mDayPaint.setColor(dayTextColor);
+
+            canvas.drawText("" + day, x, centerY - halfLineHeight, mDayPaint);
+
+            j++;
+
+            if (j == DAYS_IN_WEEK) {
+                j = 0;
+                centerY += mDayHeight;
+            }
+        }
     }
 
     private static boolean isValidDayOfWeek(int day) {
@@ -288,18 +424,52 @@
     }
 
     /**
-     * Sets all the parameters for displaying this week. Parameters have a default value and
-     * will only update if a new value is included, except for focus month, which will always
-     * default to no focus month if no value is passed in. The only required parameter is the
-     * week start.
+     * Sets the selected day.
      *
-     * @param selectedDay the selected day of the month, or -1 for no selection.
-     * @param month the month.
-     * @param year the year.
-     * @param weekStart which day the week should start on. {@link Calendar#SUNDAY} through
-     *        {@link Calendar#SATURDAY}.
-     * @param enabledDayStart the first enabled day.
-     * @param enabledDayEnd the last enabled day.
+     * @param dayOfMonth the selected day of the month, or {@code -1} to clear
+     *                   the selection
+     */
+    public void setSelectedDay(int dayOfMonth) {
+        mActivatedDay = dayOfMonth;
+
+        // Invalidate cached accessibility information.
+        mTouchHelper.invalidateRoot();
+        invalidate();
+    }
+
+    /**
+     * Sets the first day of the week.
+     *
+     * @param weekStart which day the week should start on, valid values are
+     *                  {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY}
+     */
+    public void setFirstDayOfWeek(int weekStart) {
+        if (isValidDayOfWeek(weekStart)) {
+            mWeekStart = weekStart;
+        } else {
+            mWeekStart = mCalendar.getFirstDayOfWeek();
+        }
+
+        // Invalidate cached accessibility information.
+        mTouchHelper.invalidateRoot();
+        invalidate();
+    }
+
+    /**
+     * Sets all the parameters for displaying this week.
+     * <p>
+     * Parameters have a default value and will only update if a new value is
+     * included, except for focus month, which will always default to no focus
+     * month if no value is passed in. The only required parameter is the week
+     * start.
+     *
+     * @param selectedDay the selected day of the month, or -1 for no selection
+     * @param month the month
+     * @param year the year
+     * @param weekStart which day the week should start on, valid values are
+     *                  {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY}
+     * @param enabledDayStart the first enabled day
+     * @param enabledDayEnd the last enabled day
      */
     void setMonthParams(int selectedDay, int month, int year, int weekStart, int enabledDayStart,
             int enabledDayEnd) {
@@ -310,12 +480,6 @@
         }
         mYear = year;
 
-        // Figure out what day today is
-        final Time today = new Time(Time.getCurrentTimezone());
-        today.setToNow();
-        mHasToday = false;
-        mToday = -1;
-
         mCalendar.set(Calendar.MONTH, mMonth);
         mCalendar.set(Calendar.YEAR, mYear);
         mCalendar.set(Calendar.DAY_OF_MONTH, 1);
@@ -334,15 +498,20 @@
             mEnabledDayEnd = enabledDayEnd;
         }
 
-        mNumCells = getDaysInMonth(mMonth, mYear);
-        for (int i = 0; i < mNumCells; i++) {
+        // Figure out what day today is.
+        final Calendar today = Calendar.getInstance();
+        mToday = -1;
+        mDaysInMonth = getDaysInMonth(mMonth, mYear);
+        for (int i = 0; i < mDaysInMonth; i++) {
             final int day = i + 1;
             if (sameDay(day, today)) {
-                mHasToday = true;
                 mToday = day;
             }
         }
-        mNumRows = calculateNumRows();
+        mNumWeeks = calculateNumRows();
+
+        // Invalidate the old title.
+        mTitle = null;
 
         // Invalidate cached accessibility information.
         mTouchHelper.invalidateRoot();
@@ -371,154 +540,118 @@
     }
 
     public void reuse() {
-        mNumRows = DEFAULT_NUM_ROWS;
+        mNumWeeks = MAX_WEEKS_IN_MONTH;
         requestLayout();
     }
 
     private int calculateNumRows() {
-        int offset = findDayOffset();
-        int dividend = (offset + mNumCells) / mNumDays;
-        int remainder = (offset + mNumCells) % mNumDays;
-        return (dividend + (remainder > 0 ? 1 : 0));
+        final int offset = findDayOffset();
+        final int dividend = (offset + mDaysInMonth) / DAYS_IN_WEEK;
+        final int remainder = (offset + mDaysInMonth) % DAYS_IN_WEEK;
+        return dividend + (remainder > 0 ? 1 : 0);
     }
 
-    private boolean sameDay(int day, Time today) {
-        return mYear == today.year &&
-                mMonth == today.month &&
-                day == today.monthDay;
+    private boolean sameDay(int day, Calendar today) {
+        return mYear == today.get(Calendar.YEAR) && mMonth == today.get(Calendar.MONTH)
+                && day == today.get(Calendar.DAY_OF_MONTH);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mRowHeight * mNumRows
-                + mMonthHeaderHeight);
+        final int preferredHeight = mDayHeight * mNumWeeks + mDayOfWeekHeight + mMonthHeight
+                + getPaddingTop() + getPaddingBottom();
+        final int preferredWidth = mCellWidth * DAYS_IN_WEEK
+                + getPaddingStart() + getPaddingEnd();
+        final int resolvedWidth = resolveSize(preferredWidth, widthMeasureSpec);
+        final int resolvedHeight = resolveSize(preferredHeight, heightMeasureSpec);
+        setMeasuredDimension(resolvedWidth, resolvedHeight);
     }
 
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        mWidth = w;
+        mPaddedWidth = w - getPaddingLeft() - getPaddingRight();
+        mPaddedHeight = w - getPaddingTop() - getPaddingBottom();
 
         // Invalidate cached accessibility information.
         mTouchHelper.invalidateRoot();
     }
 
-    private String getMonthAndYearString() {
-        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
-                | DateUtils.FORMAT_NO_MONTH_DAY;
-        mStringBuilder.setLength(0);
-        long millis = mCalendar.getTimeInMillis();
-        return DateUtils.formatDateRange(getContext(), mFormatter, millis, millis, flags,
-                Time.getCurrentTimezone()).toString();
-    }
-
-    private void drawMonthTitle(Canvas canvas) {
-        final float x = (mWidth + 2 * mPadding) / 2f;
-
-        // Centered on the upper half of the month header.
-        final float lineHeight = mMonthPaint.ascent() + mMonthPaint.descent();
-        final float y = mMonthHeaderHeight * 0.25f - lineHeight / 2f;
-
-        canvas.drawText(getMonthAndYearString(), x, y, mMonthPaint);
-    }
-
-    private void drawWeekDayLabels(Canvas canvas) {
-        final float dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
-
-        // Centered on the lower half of the month header.
-        final float lineHeight = mDayOfWeekPaint.ascent() + mDayOfWeekPaint.descent();
-        final float y = mMonthHeaderHeight * 0.75f - lineHeight / 2f;
-
-        for (int i = 0; i < mNumDays; i++) {
-            final int calendarDay = (i + mWeekStart) % mNumDays;
-            mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay);
-
-            final String dayLabel = mDayFormatter.format(mDayLabelCalendar.getTime());
-            final float x = (2 * i + 1) * dayWidthHalf + mPadding;
-            canvas.drawText(dayLabel, x, y, mDayOfWeekPaint);
-        }
-    }
-
-    /**
-     * Draws the month days.
-     */
-    private void drawDays(Canvas canvas) {
-        final int dayWidthHalf = (mWidth - mPadding * 2) / (mNumDays * 2);
-
-        // Centered within the row.
-        final float lineHeight = mDayOfWeekPaint.ascent() + mDayOfWeekPaint.descent();
-        float y = mMonthHeaderHeight + (mRowHeight - lineHeight) / 2f;
-
-        for (int day = 1, j = findDayOffset(); day <= mNumCells; day++) {
-            final int x = (2 * j + 1) * dayWidthHalf + mPadding;
-            int stateMask = 0;
-
-            if (day >= mEnabledDayStart && day <= mEnabledDayEnd) {
-                stateMask |= StateSet.VIEW_STATE_ENABLED;
-            }
-
-            if (mActivatedDay == day) {
-                stateMask |= StateSet.VIEW_STATE_ACTIVATED;
-
-                // Adjust the circle to be centered the row.
-                final float rowCenterY = y + lineHeight / 2;
-                canvas.drawCircle(x, rowCenterY, mRowHeight / 2,
-                        mDayBackgroundPaint);
-            }
-
-            final int[] stateSet = StateSet.get(stateMask);
-            final int dayTextColor = mDayTextColor.getColorForState(stateSet, 0);
-            mDayPaint.setColor(dayTextColor);
-
-            final boolean isDayToday = mHasToday && mToday == day;
-            mDayPaint.setFakeBoldText(isDayToday);
-
-            canvas.drawText(String.format("%d", day), x, y, mDayPaint);
-
-            j++;
-
-            if (j == mNumDays) {
-                j = 0;
-                y += mRowHeight;
-            }
-        }
-    }
-
     private int findDayOffset() {
-        return (mDayOfWeekStart < mWeekStart ? (mDayOfWeekStart + mNumDays) : mDayOfWeekStart)
-                - mWeekStart;
+        final int offset = mDayOfWeekStart - mWeekStart;
+        if (mDayOfWeekStart < mWeekStart) {
+            return offset + DAYS_IN_WEEK;
+        }
+        return offset;
     }
 
     /**
-     * Calculates the day that the given x position is in, accounting for week
-     * number. Returns the day or -1 if the position wasn't in a day.
+     * Calculates the day of the month at the specified touch position. Returns
+     * the day of the month or -1 if the position wasn't in a valid day.
      *
-     * @param x The x position of the touch event
-     * @return The day number, or -1 if the position wasn't in a day
+     * @param x the x position of the touch event
+     * @param y the y position of the touch event
+     * @return the day of the month at (x, y) or -1 if the position wasn't in a
+     *         valid day
      */
-    private int getDayFromLocation(float x, float y) {
-        int dayStart = mPadding;
-        if (x < dayStart || x > mWidth - mPadding) {
+    private int getDayAtLocation(float x, float y) {
+        final int paddedX = (int) (x - getPaddingLeft() + 0.5f);
+        if (paddedX < 0 || paddedX >= mPaddedWidth) {
             return -1;
         }
-        // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
-        int row = (int) (y - mMonthHeaderHeight) / mRowHeight;
-        int column = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mPadding));
 
-        int day = column - findDayOffset() + 1;
-        day += row * mNumDays;
-        if (day < 1 || day > mNumCells) {
+        final int headerHeight = mMonthHeight + mDayOfWeekHeight;
+        final int paddedY = (int) (y - getPaddingTop() + 0.5f);
+        if (paddedY < headerHeight || paddedY >= mPaddedHeight) {
             return -1;
         }
+
+        final int row = (paddedY - headerHeight) / mDayHeight;
+        final int col = (paddedX * DAYS_IN_WEEK) / mPaddedWidth;
+        final int index = col + row * DAYS_IN_WEEK;
+        final int day = index + 1 - findDayOffset();
+        if (day < 1 || day > mDaysInMonth) {
+            return -1;
+        }
+
         return day;
     }
 
     /**
+     * Calculates the bounds of the specified day.
+     *
+     * @param day the day of the month
+     * @param outBounds the rect to populate with bounds
+     */
+    private boolean getBoundsForDay(int day, Rect outBounds) {
+        if (day < 1 || day > mDaysInMonth) {
+            return false;
+        }
+
+        final int index = day - 1 + findDayOffset();
+        final int row = index / DAYS_IN_WEEK;
+        final int col = index % DAYS_IN_WEEK;
+
+        final int headerHeight = mMonthHeight + mDayOfWeekHeight;
+        final int paddedY = row * mDayHeight + headerHeight;
+        final int paddedX = col * mPaddedWidth;
+
+        final int y = paddedY + getPaddingTop();
+        final int x = paddedX + getPaddingLeft();
+
+        final int cellHeight = mDayHeight;
+        final int cellWidth = mPaddedWidth / DAYS_IN_WEEK;
+        outBounds.set(x, y, (x + cellWidth), (y + cellHeight));
+
+        return true;
+    }
+
+    /**
      * Called when the user clicks on a day. Handles callbacks to the
      * {@link OnDayClickListener} if one is set.
      *
-     * @param day The day that was clicked
+     * @param day the day that was clicked
      */
-    private void onDayClick(int day) {
+    private void onDayClicked(int day) {
         if (mOnDayClickListener != null) {
             Calendar date = Calendar.getInstance();
             date.set(mYear, mMonth, day);
@@ -530,44 +663,6 @@
     }
 
     /**
-     * @return The date that has accessibility focus, or {@code null} if no date
-     *         has focus
-     */
-    Calendar getAccessibilityFocus() {
-        final int day = mTouchHelper.getFocusedVirtualView();
-        Calendar date = null;
-        if (day >= 0) {
-            date = Calendar.getInstance();
-            date.set(mYear, mMonth, day);
-        }
-        return date;
-    }
-
-    /**
-     * Clears accessibility focus within the view. No-op if the view does not
-     * contain accessibility focus.
-     */
-    public void clearAccessibilityFocus() {
-        mTouchHelper.clearFocusedVirtualView();
-    }
-
-    /**
-     * Attempts to restore accessibility focus to the specified date.
-     *
-     * @param day The date which should receive focus
-     * @return {@code false} if the date is not valid for this month view, or
-     *         {@code true} if the date received focus
-     */
-    boolean restoreAccessibilityFocus(Calendar day) {
-        if ((day.get(Calendar.YEAR) != mYear) || (day.get(Calendar.MONTH) != mMonth) ||
-                (day.get(Calendar.DAY_OF_MONTH) > mNumCells)) {
-            return false;
-        }
-        mTouchHelper.setFocusedVirtualView(day.get(Calendar.DAY_OF_MONTH));
-        return true;
-    }
-
-    /**
      * Provides a virtual view hierarchy for interfacing with an accessibility
      * service.
      */
@@ -581,24 +676,9 @@
             super(host);
         }
 
-        public void setFocusedVirtualView(int virtualViewId) {
-            getAccessibilityNodeProvider(SimpleMonthView.this).performAction(
-                    virtualViewId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
-        }
-
-        public void clearFocusedVirtualView() {
-            final int focusedVirtualView = getFocusedVirtualView();
-            if (focusedVirtualView != ExploreByTouchHelper.INVALID_ID) {
-                getAccessibilityNodeProvider(SimpleMonthView.this).performAction(
-                        focusedVirtualView,
-                        AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS,
-                        null);
-            }
-        }
-
         @Override
         protected int getVirtualViewAt(float x, float y) {
-            final int day = getDayFromLocation(x, y);
+            final int day = getDayAtLocation(x, y);
             if (day >= 0) {
                 return day;
             }
@@ -607,7 +687,7 @@
 
         @Override
         protected void getVisibleVirtualViews(IntArray virtualViewIds) {
-            for (int day = 1; day <= mNumCells; day++) {
+            for (int day = 1; day <= mDaysInMonth; day++) {
                 virtualViewIds.add(day);
             }
         }
@@ -619,11 +699,20 @@
 
         @Override
         protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) {
-            getItemBounds(virtualViewId, mTempRect);
+            final boolean hasBounds = getBoundsForDay(virtualViewId, mTempRect);
+
+            if (!hasBounds) {
+                // The day is invalid, kill the node.
+                mTempRect.setEmpty();
+                node.setContentDescription("");
+                node.setBoundsInParent(mTempRect);
+                node.setVisibleToUser(false);
+                return;
+            }
 
             node.setContentDescription(getItemDescription(virtualViewId));
             node.setBoundsInParent(mTempRect);
-            node.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+            node.addAction(AccessibilityAction.ACTION_CLICK);
 
             if (virtualViewId == mActivatedDay) {
                 node.setSelected(true);
@@ -636,7 +725,7 @@
                 Bundle arguments) {
             switch (action) {
                 case AccessibilityNodeInfo.ACTION_CLICK:
-                    onDayClick(virtualViewId);
+                    onDayClicked(virtualViewId);
                     return true;
             }
 
@@ -644,26 +733,6 @@
         }
 
         /**
-         * Calculates the bounding rectangle of a given time object.
-         *
-         * @param day The day to calculate bounds for
-         * @param rect The rectangle in which to store the bounds
-         */
-        private void getItemBounds(int day, Rect rect) {
-            final int offsetX = mPadding;
-            final int offsetY = mMonthHeaderHeight;
-            final int cellHeight = mRowHeight;
-            final int cellWidth = ((mWidth - (2 * mPadding)) / mNumDays);
-            final int index = ((day - 1) + findDayOffset());
-            final int row = (index / mNumDays);
-            final int column = (index % mNumDays);
-            final int x = (offsetX + (column * cellWidth));
-            final int y = (offsetY + (row * cellHeight));
-
-            rect.set(x, y, (x + cellWidth), (y + cellHeight));
-        }
-
-        /**
          * Generates a description for a given time object. Since this
          * description will be spoken, the components are ordered by descending
          * specificity as DAY MONTH YEAR.
diff --git a/core/java/android/widget/TextViewWithCircularIndicator.java b/core/java/android/widget/TextViewWithCircularIndicator.java
deleted file mode 100644
index d3c786c..0000000
--- a/core/java/android/widget/TextViewWithCircularIndicator.java
+++ /dev/null
@@ -1,87 +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.
- */
-
-package android.widget;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.util.AttributeSet;
-
-import com.android.internal.R;
-
-class TextViewWithCircularIndicator extends TextView {
-    private final Paint mCirclePaint = new Paint();
-    private final String mItemIsSelectedText;
-
-    public TextViewWithCircularIndicator(Context context) {
-        this(context, null);
-    }
-
-    public TextViewWithCircularIndicator(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TextViewWithCircularIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public TextViewWithCircularIndicator(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-
-        final Resources res = context.getResources();
-        mItemIsSelectedText = res.getString(R.string.item_is_selected);
-
-        init();
-    }
-
-    private void init() {
-        mCirclePaint.setTypeface(Typeface.create(mCirclePaint.getTypeface(), Typeface.BOLD));
-        mCirclePaint.setAntiAlias(true);
-        mCirclePaint.setTextAlign(Paint.Align.CENTER);
-        mCirclePaint.setStyle(Paint.Style.FILL);
-    }
-
-    public void setCircleColor(int color) {
-        mCirclePaint.setColor(color);
-        invalidate();
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        if (isActivated()) {
-            final int width = getWidth();
-            final int height = getHeight();
-            final int radius = Math.min(width, height) / 2;
-            canvas.drawCircle(width / 2, height / 2, radius, mCirclePaint);
-        }
-
-        super.onDraw(canvas);
-    }
-
-    @Override
-    public CharSequence getContentDescription() {
-        final CharSequence itemText = getText();
-        if (isActivated()) {
-            return String.format(mItemIsSelectedText, itemText);
-        } else {
-            return itemText;
-        }
-    }
-}
\ No newline at end of file
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 6f0465f..7bd502e 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -17,10 +17,9 @@
 package android.widget;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.util.AttributeSet;
-import android.util.StateSet;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -32,23 +31,14 @@
 /**
  * Displays a selectable list of years.
  */
-class YearPickerView extends ListView implements AdapterView.OnItemClickListener,
-        OnDateChangedListener {
-    private final Calendar mMinDate = Calendar.getInstance();
-    private final Calendar mMaxDate = Calendar.getInstance();
-
+class YearPickerView extends ListView {
     private final YearAdapter mAdapter;
     private final int mViewSize;
     private final int mChildSize;
 
-    private DatePickerController mController;
+    private OnYearSelectedListener mOnYearSelectedListener;
 
-    private int mSelectedPosition = -1;
-    private int mYearActivatedColor;
-
-    public YearPickerView(Context context) {
-        this(context, null);
-    }
+    private long mCurrentTimeMillis;
 
     public YearPickerView(Context context, AttributeSet attrs) {
         this(context, attrs, R.attr.listViewStyle);
@@ -69,104 +59,187 @@
         mViewSize = res.getDimensionPixelOffset(R.dimen.datepicker_view_animator_height);
         mChildSize = res.getDimensionPixelOffset(R.dimen.datepicker_year_label_height);
 
-        setVerticalFadingEdgeEnabled(true);
-        setFadingEdgeLength(mChildSize / 3);
+        setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final int year = mAdapter.getYearForPosition(position);
+                mAdapter.setSelection(year);
 
-        final int paddingTop = res.getDimensionPixelSize(
-                R.dimen.datepicker_year_picker_padding_top);
-        setPadding(0, paddingTop, 0, 0);
+                if (mOnYearSelectedListener != null) {
+                    mOnYearSelectedListener.onYearChanged(YearPickerView.this, year);
+                }
+            }
+        });
 
-        setOnItemClickListener(this);
-        setDividerHeight(0);
-
-        mAdapter = new YearAdapter(getContext(), R.layout.year_label_text_view);
+        mAdapter = new YearAdapter(getContext());
         setAdapter(mAdapter);
     }
 
+    public void setOnYearSelectedListener(OnYearSelectedListener listener) {
+        mOnYearSelectedListener = listener;
+    }
+
+    public void setDate(long currentTimeMillis) {
+        mCurrentTimeMillis = currentTimeMillis;
+    }
+
+    /**
+     * Sets the currently selected year. Jumps immediately to the new year.
+     *
+     * @param year the target year
+     */
+    public void setYear(final int year) {
+        mAdapter.setSelection(year);
+
+        post(new Runnable() {
+            @Override
+            public void run() {
+                final int position = mAdapter.getPositionForYear(year);
+                if (position >= 0 && position < getCount()) {
+                    setSelectionCentered(position);
+                }
+            }
+        });
+    }
+
+    public void setSelectionCentered(int position) {
+        final int offset = mViewSize / 2 - mChildSize / 2;
+        setSelectionFromTop(position, offset);
+    }
+
     public void setRange(Calendar min, Calendar max) {
-        mMinDate.setTimeInMillis(min.getTimeInMillis());
-        mMaxDate.setTimeInMillis(max.getTimeInMillis());
-
-        updateAdapterData();
-    }
-
-    public void init(DatePickerController controller) {
-        mController = controller;
-        mController.registerOnDateChangedListener(this);
-
-        updateAdapterData();
-
-        onDateChanged();
-    }
-
-    public void setYearBackgroundColor(ColorStateList yearBackgroundColor) {
-        mYearActivatedColor = yearBackgroundColor.getColorForState(
-                StateSet.get(StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED), 0);
-        invalidate();
+        mAdapter.setRange(min, max);
     }
 
     public void setYearTextAppearance(int resId) {
         mAdapter.setItemTextAppearance(resId);
     }
 
-    private void updateAdapterData() {
-        mAdapter.clear();
-
-        final int maxYear = mMaxDate.get(Calendar.YEAR);
-        for (int year = mMinDate.get(Calendar.YEAR); year <= maxYear; year++) {
-            mAdapter.add(year);
-        }
+    public void setYearActivatedTextAppearance(int resId) {
+        mAdapter.setItemActivatedTextAppearance(resId);
     }
 
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        mController.tryVibrate();
-        if (position != mSelectedPosition) {
-            mSelectedPosition = position;
-            mAdapter.notifyDataSetChanged();
-        }
-        mController.onYearSelected(mAdapter.getItem(position));
-    }
+    private static class YearAdapter extends BaseAdapter {
+        private static final int ITEM_LAYOUT = R.layout.year_label_text_view;
 
-    private class YearAdapter extends ArrayAdapter<Integer> {
+        private final LayoutInflater mInflater;
+
+        private int mActivatedYear;
+        private int mMinYear;
+        private int mCount;
+
         private int mItemTextAppearanceResId;
+        private int mItemActivatedTextAppearanceResId;
 
-        public YearAdapter(Context context, int resource) {
-            super(context, resource);
+        public YearAdapter(Context context) {
+            mInflater = LayoutInflater.from(context);
         }
 
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final TextViewWithCircularIndicator v = (TextViewWithCircularIndicator)
-                    super.getView(position, convertView, parent);
-            v.setTextAppearance(v.getContext(), mItemTextAppearanceResId);
-            v.setCircleColor(mYearActivatedColor);
+        public void setRange(Calendar minDate, Calendar maxDate) {
+            final int minYear = minDate.get(Calendar.YEAR);
+            final int count = maxDate.get(Calendar.YEAR) - minYear + 1;
 
-            final int year = getItem(position);
-            final boolean selected = mController.getSelectedDay().get(Calendar.YEAR) == year;
-            v.setActivated(selected);
+            if (mMinYear != minYear || mCount != count) {
+                mMinYear = minYear;
+                mCount = count;
+                notifyDataSetInvalidated();
+            }
+        }
 
-            return v;
+        public boolean setSelection(int year) {
+            if (mActivatedYear != year) {
+                mActivatedYear = year;
+                notifyDataSetChanged();
+                return true;
+            }
+            return false;
         }
 
         public void setItemTextAppearance(int resId) {
             mItemTextAppearanceResId = resId;
+            notifyDataSetChanged();
         }
-    }
 
-    public void postSetSelectionCentered(final int position) {
-        postSetSelectionFromTop(position, mViewSize / 2 - mChildSize / 2);
-    }
+        public void setItemActivatedTextAppearance(int resId) {
+            mItemActivatedTextAppearanceResId = resId;
+            notifyDataSetChanged();
+        }
 
-    public void postSetSelectionFromTop(final int position, final int offset) {
-        post(new Runnable() {
+        @Override
+        public int getCount() {
+            return mCount;
+        }
 
-            @Override
-            public void run() {
-                setSelectionFromTop(position, offset);
-                requestLayout();
+        @Override
+        public Integer getItem(int position) {
+            return getYearForPosition(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return getYearForPosition(position);
+        }
+
+        public int getPositionForYear(int year) {
+            return year - mMinYear;
+        }
+
+        public int getYearForPosition(int position) {
+            return mMinYear + position;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = mInflater.inflate(ITEM_LAYOUT, parent, false);
             }
-        });
+
+            final int year = getYearForPosition(position);
+            final boolean activated = mActivatedYear == year;
+
+            final int textAppearanceResId;
+            if (activated && mItemActivatedTextAppearanceResId != 0) {
+                textAppearanceResId = mItemActivatedTextAppearanceResId;
+            } else {
+                textAppearanceResId = mItemTextAppearanceResId;
+            }
+
+            final TextView v = (TextView) convertView;
+            v.setText("" + year);
+            v.setTextAppearance(v.getContext(), textAppearanceResId);
+            v.setActivated(activated);
+            return v;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return false;
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return true;
+        }
     }
 
     public int getFirstPositionOffset() {
@@ -177,22 +250,28 @@
         return firstChild.getTop();
     }
 
-    @Override
-    public void onDateChanged() {
-        updateAdapterData();
-        mAdapter.notifyDataSetChanged();
-        postSetSelectionCentered(
-                mController.getSelectedDay().get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR));
-    }
-
     /** @hide */
     @Override
     public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
         super.onInitializeAccessibilityEventInternal(event);
 
+        // There are a bunch of years, so don't bother.
         if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
             event.setFromIndex(0);
             event.setToIndex(0);
         }
     }
+
+    /**
+     * The callback used to indicate the user changed the year.
+     */
+    public interface OnYearSelectedListener {
+        /**
+         * Called upon a year change.
+         *
+         * @param view The view associated with this listener.
+         * @param year The year that was set.
+         */
+        void onYearChanged(YearPickerView view, int year);
+    }
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 02f675c..f479f4f 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -33,6 +33,7 @@
 import android.content.pm.PackageParser.PackageParserException;
 import android.os.Build;
 import android.os.SELinux;
+import android.os.SystemProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Slog;
@@ -74,6 +75,7 @@
 
         final long[] apkHandles;
         final boolean multiArch;
+        final boolean extractNativeLibs;
 
         public static Handle create(File packageFile) throws IOException {
             try {
@@ -86,14 +88,16 @@
 
         public static Handle create(Package pkg) throws IOException {
             return create(pkg.getAllCodePaths(),
-                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0);
+                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
+                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0);
         }
 
         public static Handle create(PackageLite lite) throws IOException {
-            return create(lite.getAllCodePaths(), lite.multiArch);
+            return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs);
         }
 
-        private static Handle create(List<String> codePaths, boolean multiArch) throws IOException {
+        private static Handle create(List<String> codePaths, boolean multiArch,
+                boolean extractNativeLibs) throws IOException {
             final int size = codePaths.size();
             final long[] apkHandles = new long[size];
             for (int i = 0; i < size; i++) {
@@ -108,12 +112,13 @@
                 }
             }
 
-            return new Handle(apkHandles, multiArch);
+            return new Handle(apkHandles, multiArch, extractNativeLibs);
         }
 
-        Handle(long[] apkHandles, boolean multiArch) {
+        Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs) {
             this.apkHandles = apkHandles;
             this.multiArch = multiArch;
+            this.extractNativeLibs = extractNativeLibs;
             mGuard.open("close");
         }
 
@@ -146,8 +151,8 @@
 
     private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
 
-    private native static int nativeCopyNativeBinaries(long handle,
-            String sharedLibraryPath, String abiToCopy);
+    private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
+            String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge);
 
     private static long sumNativeBinaries(Handle handle, String abi) {
         long sum = 0;
@@ -167,7 +172,8 @@
      */
     public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
         for (long apkHandle : handle.apkHandles) {
-            int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi);
+            int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
+                    handle.extractNativeLibs, HAS_NATIVE_BRIDGE);
             if (res != INSTALL_SUCCEEDED) {
                 return res;
             }
@@ -218,7 +224,8 @@
     /**
      * Remove the native binaries of a given package. This deletes the files
      */
-    public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot, boolean deleteRootDir) {
+    public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot,
+            boolean deleteRootDir) {
         if (DEBUG_NATIVE) {
             Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryRoot.getPath());
         }
@@ -247,7 +254,8 @@
             // asked to or this will prevent installation of future updates.
             if (deleteRootDir) {
                 if (!nativeLibraryRoot.delete()) {
-                    Slog.w(TAG, "Could not delete native binary directory: " + nativeLibraryRoot.getPath());
+                    Slog.w(TAG, "Could not delete native binary directory: " +
+                            nativeLibraryRoot.getPath());
                 }
             }
         }
@@ -416,6 +424,9 @@
     // We don't care about the other return values for now.
     private static final int BITCODE_PRESENT = 1;
 
+    private static final boolean HAS_NATIVE_BRIDGE =
+            !"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0"));
+
     private static native int hasRenderscriptBitcode(long apkHandle);
 
     public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 57fcf57..06bdb24 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -764,17 +764,55 @@
         private int[] mCurrentProfileIds = new int[0];
 
         private static void buildEnabledInputMethodsSettingString(
-                StringBuilder builder, Pair<String, ArrayList<String>> pair) {
-            String id = pair.first;
-            ArrayList<String> subtypes = pair.second;
-            builder.append(id);
+                StringBuilder builder, Pair<String, ArrayList<String>> ime) {
+            builder.append(ime.first);
             // Inputmethod and subtypes are saved in the settings as follows:
             // ime0;subtype0;subtype1:ime1;subtype0:ime2:ime3;subtype0;subtype1
-            for (String subtypeId: subtypes) {
+            for (String subtypeId: ime.second) {
                 builder.append(INPUT_METHOD_SUBTYPE_SEPARATER).append(subtypeId);
             }
         }
 
+        public static String buildInputMethodsSettingString(
+                List<Pair<String, ArrayList<String>>> allImeSettingsMap) {
+            final StringBuilder b = new StringBuilder();
+            boolean needsSeparator = false;
+            for (Pair<String, ArrayList<String>> ime : allImeSettingsMap) {
+                if (needsSeparator) {
+                    b.append(INPUT_METHOD_SEPARATER);
+                }
+                buildEnabledInputMethodsSettingString(b, ime);
+                needsSeparator = true;
+            }
+            return b.toString();
+        }
+
+        public static List<Pair<String, ArrayList<String>>> buildInputMethodsAndSubtypeList(
+                String enabledInputMethodsStr,
+                TextUtils.SimpleStringSplitter inputMethodSplitter,
+                TextUtils.SimpleStringSplitter subtypeSplitter) {
+            ArrayList<Pair<String, ArrayList<String>>> imsList =
+                    new ArrayList<Pair<String, ArrayList<String>>>();
+            if (TextUtils.isEmpty(enabledInputMethodsStr)) {
+                return imsList;
+            }
+            inputMethodSplitter.setString(enabledInputMethodsStr);
+            while (inputMethodSplitter.hasNext()) {
+                String nextImsStr = inputMethodSplitter.next();
+                subtypeSplitter.setString(nextImsStr);
+                if (subtypeSplitter.hasNext()) {
+                    ArrayList<String> subtypeHashes = new ArrayList<String>();
+                    // The first element is ime id.
+                    String imeId = subtypeSplitter.next();
+                    while (subtypeSplitter.hasNext()) {
+                        subtypeHashes.add(subtypeSplitter.next());
+                    }
+                    imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes));
+                }
+            }
+            return imsList;
+        }
+
         public InputMethodSettings(
                 Resources res, ContentResolver resolver,
                 HashMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
@@ -875,27 +913,9 @@
         }
 
         public List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() {
-            ArrayList<Pair<String, ArrayList<String>>> imsList
-                    = new ArrayList<Pair<String, ArrayList<String>>>();
-            final String enabledInputMethodsStr = getEnabledInputMethodsStr();
-            if (TextUtils.isEmpty(enabledInputMethodsStr)) {
-                return imsList;
-            }
-            mInputMethodSplitter.setString(enabledInputMethodsStr);
-            while (mInputMethodSplitter.hasNext()) {
-                String nextImsStr = mInputMethodSplitter.next();
-                mSubtypeSplitter.setString(nextImsStr);
-                if (mSubtypeSplitter.hasNext()) {
-                    ArrayList<String> subtypeHashes = new ArrayList<String>();
-                    // The first element is ime id.
-                    String imeId = mSubtypeSplitter.next();
-                    while (mSubtypeSplitter.hasNext()) {
-                        subtypeHashes.add(mSubtypeSplitter.next());
-                    }
-                    imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes));
-                }
-            }
-            return imsList;
+            return buildInputMethodsAndSubtypeList(getEnabledInputMethodsStr(),
+                    mInputMethodSplitter,
+                    mSubtypeSplitter);
         }
 
         public void appendAndPutEnabledInputMethodLocked(String id, boolean reloadInputMethodStr) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 7d5df46..65a970a 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -7422,7 +7422,9 @@
         updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
         // TODO(adamlesinski): enable when bluedroid stops deadlocking. b/19248786
         // updateBluetoothControllerActivityLocked();
-        updateWifiControllerActivityLocked();
+        // TODO(adamlesinski): disabled to avoid deadlock. Need to change how external
+        // data is pulled/accessed from BatteryStats. b/19729960
+        // updateWifiControllerActivityLocked();
         if (mOnBatteryInternal) {
             final boolean screenOn = mScreenState == Display.STATE_ON;
             updateDischargeScreenLevelsLocked(screenOn, screenOn);
diff --git a/core/java/com/android/internal/util/ScreenShapeHelper.java b/core/java/com/android/internal/util/ScreenShapeHelper.java
new file mode 100644
index 0000000..1bcc7a0
--- /dev/null
+++ b/core/java/com/android/internal/util/ScreenShapeHelper.java
@@ -0,0 +1,48 @@
+package com.android.internal.util;
+
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.ViewRootImpl;
+
+import com.android.internal.R;
+
+/**
+ * @hide
+ */
+public class ScreenShapeHelper {
+    private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
+
+    /**
+     * Return the bottom pixel window outset of a window given its style attributes.
+     * @param displayMetrics Display metrics of the current device
+     * @param windowStyle Window style attributes for the window.
+     * @return An outset dimension in pixels or 0 if no outset should be applied.
+     */
+    public static int getWindowOutsetBottomPx(DisplayMetrics displayMetrics,
+            TypedArray windowStyle) {
+        if (IS_EMULATOR) {
+            return SystemProperties.getInt(ViewRootImpl.PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX, 0);
+        } else if (windowStyle.hasValue(R.styleable.Window_windowOutsetBottom)) {
+            TypedValue outsetBottom = new TypedValue();
+            windowStyle.getValue(R.styleable.Window_windowOutsetBottom, outsetBottom);
+            return (int) outsetBottom.getDimension(displayMetrics);
+        }
+        return 0;
+    }
+
+    /**
+     * Get whether a device has has a round screen.
+     */
+    public static boolean getWindowIsRound(Resources resources) {
+        if (IS_EMULATOR) {
+            return SystemProperties.getBoolean(ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false);
+        } else {
+            return resources.getBoolean(
+                    com.android.internal.R.bool.config_windowIsRound);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/AccessibleDateAnimator.java b/core/java/com/android/internal/widget/AccessibleDateAnimator.java
deleted file mode 100644
index f97a5d1..0000000
--- a/core/java/com/android/internal/widget/AccessibleDateAnimator.java
+++ /dev/null
@@ -1,56 +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.
- */
-
-package com.android.internal.widget;
-
-import android.content.Context;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ViewAnimator;
-
-/**
- * @hide
- */
-public class AccessibleDateAnimator extends ViewAnimator {
-    private long mDateMillis;
-
-    public AccessibleDateAnimator(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setDateMillis(long dateMillis) {
-        mDateMillis = dateMillis;
-    }
-
-    /**
-     * Announce the currently-selected date when launched.
-     */
-    @Override
-    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
-            // Clear the event's current text so that only the current date will be spoken.
-            event.getText().clear();
-            int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR |
-                    DateUtils.FORMAT_SHOW_WEEKDAY;
-
-            String dateString = DateUtils.formatDateTime(getContext(), mDateMillis, flags);
-            event.getText().add(dateString);
-            return true;
-        }
-        return super.dispatchPopulateAccessibilityEventInternal(event);
-    }
-}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index f916e6f..8018942 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -137,7 +137,7 @@
     private int mRestoredCurItem = -1;
     private Parcelable mRestoredAdapterState = null;
     private ClassLoader mRestoredClassLoader = null;
-    private Scroller mScroller;
+    private final Scroller mScroller;
     private PagerObserver mObserver;
 
     private int mPageMargin;
@@ -162,9 +162,9 @@
 
     private boolean mIsBeingDragged;
     private boolean mIsUnableToDrag;
-    private int mDefaultGutterSize;
+    private final int mDefaultGutterSize;
     private int mGutterSize;
-    private int mTouchSlop;
+    private final int mTouchSlop;
     /**
      * Position of the last motion event.
      */
@@ -187,10 +187,10 @@
      * Determines speed during touch scrolling
      */
     private VelocityTracker mVelocityTracker;
-    private int mMinimumVelocity;
-    private int mMaximumVelocity;
-    private int mFlingDistance;
-    private int mCloseEnough;
+    private final int mMinimumVelocity;
+    private final int mMaximumVelocity;
+    private final int mFlingDistance;
+    private final int mCloseEnough;
 
     // If the pager is at least this close to its final position, complete the scroll
     // on touch down and let the user interact with the content inside instead of
@@ -200,8 +200,8 @@
     private boolean mFakeDragging;
     private long mFakeDragBeginTime;
 
-    private EdgeEffect mLeftEdge;
-    private EdgeEffect mRightEdge;
+    private final EdgeEffect mLeftEdge;
+    private final EdgeEffect mRightEdge;
 
     private boolean mFirstLayout = true;
     private boolean mNeedCalculatePageOffsets = false;
@@ -339,20 +339,24 @@
     interface Decor {}
 
     public ViewPager(Context context) {
-        super(context);
-        initViewPager();
+        this(context, null);
     }
 
     public ViewPager(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initViewPager();
+        this(context, attrs, 0);
     }
 
-    void initViewPager() {
+    public ViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ViewPager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         setWillNotDraw(false);
         setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
         setFocusable(true);
-        final Context context = getContext();
+
         mScroller = new Scroller(context, sInterpolator);
         final ViewConfiguration configuration = ViewConfiguration.get(context);
         final float density = context.getResources().getDisplayMetrics().density;
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 441af15..34de6c5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -537,7 +537,6 @@
  */
 int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
 {
-    int result = -1;
     JavaVMInitArgs initArgs;
     char propBuf[PROPERTY_VALUE_MAX];
     char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
@@ -581,6 +580,7 @@
     char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
     char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
+    char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
 
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
@@ -699,7 +699,7 @@
     if (!hasFile("/system/etc/preloaded-classes")) {
         ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
               strerror(errno));
-        goto bail;
+        return -1;
     }
     addOption("-Ximage-compiler-option");
     addOption("--image-classes=/system/etc/preloaded-classes");
@@ -811,6 +811,19 @@
         addOption(nativeBridgeLibrary);
     }
 
+#if defined(__LP64__)
+    const char* cpu_abilist_property_name = "ro.product.cpu.abilist64";
+#else
+    const char* cpu_abilist_property_name = "ro.product.cpu.abilist32";
+#endif  // defined(__LP64__)
+    property_get(cpu_abilist_property_name, propBuf, "");
+    if (propBuf[0] == '\0') {
+        ALOGE("%s is not expected to be empty", cpu_abilist_property_name);
+        return -1;
+    }
+    snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);
+    addOption(cpuAbiListBuf);
+
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
     initArgs.nOptions = mOptions.size();
@@ -825,13 +838,10 @@
      */
     if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
         ALOGE("JNI_CreateJavaVM failed\n");
-        goto bail;
+        return -1;
     }
 
-    result = 0;
-
-bail:
-    return result;
+    return 0;
 }
 
 char* AndroidRuntime::toSlashClassName(const char* className)
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 2323f43..fb91c8f 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -48,6 +48,11 @@
         return NULL;
     }
 
+    ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(deviceInfo.getIdentifier().uniqueId));
+    if (!uniqueIdObj.get()) {
+        return NULL;
+    }
+
     ScopedLocalRef<jobject> kcmObj(env,
             android_view_KeyCharacterMap_create(env, deviceInfo.getId(),
             deviceInfo.getKeyCharacterMap()));
@@ -61,9 +66,9 @@
                 gInputDeviceClassInfo.ctor, deviceInfo.getId(), deviceInfo.getGeneration(),
                 deviceInfo.getControllerNumber(), nameObj.get(),
                 static_cast<int32_t>(ident.vendor), static_cast<int32_t>(ident.product),
-                descriptorObj.get(), deviceInfo.isExternal(), deviceInfo.getSources(),
-                deviceInfo.getKeyboardType(), kcmObj.get(), deviceInfo.hasVibrator(),
-                deviceInfo.hasButtonUnderPad()));
+                uniqueIdObj.get(), descriptorObj.get(), deviceInfo.isExternal(),
+                deviceInfo.getSources(), deviceInfo.getKeyboardType(), kcmObj.get(),
+                deviceInfo.hasVibrator(), deviceInfo.hasButtonUnderPad()));
 
     const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
     for (size_t i = 0; i < ranges.size(); i++) {
@@ -85,7 +90,7 @@
     gInputDeviceClassInfo.clazz = MakeGlobalRefOrDie(env, gInputDeviceClassInfo.clazz);
 
     gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
-            "(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZ)V");
+            "(IIILjava/lang/String;IILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZ)V");
 
     gInputDeviceClassInfo.addMotionRange = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz,
             "addMotionRange", "(IIFFFFF)V");
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 3c1993e..9307ff9 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -173,7 +174,11 @@
 static install_status_t
 copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
 {
-    jstring* javaNativeLibPath = (jstring*) arg;
+    void** args = reinterpret_cast<void**>(arg);
+    jstring* javaNativeLibPath = (jstring*) args[0];
+    jboolean extractNativeLibs = *(jboolean*) args[1];
+    jboolean hasNativeBridge = *(jboolean*) args[2];
+
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
 
     size_t uncompLen;
@@ -181,13 +186,31 @@
     long crc;
     time_t modTime;
 
-    if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) {
+    int method;
+    off64_t offset;
+
+    if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) {
         ALOGD("Couldn't read zip entry info\n");
         return INSTALL_FAILED_INVALID_APK;
-    } else {
-        struct tm t;
-        ZipUtils::zipTimeToTimespec(when, &t);
-        modTime = mktime(&t);
+    }
+
+    if (!extractNativeLibs) {
+        // check if library is uncompressed and page-aligned
+        if (method != ZipFileRO::kCompressStored) {
+            ALOGD("Library '%s' is compressed - will not be able to open it directly from apk.\n",
+                fileName);
+            return INSTALL_FAILED_INVALID_APK;
+        }
+
+        if (offset % PAGE_SIZE != 0) {
+            ALOGD("Library '%s' is not page-aligned - will not be able to open it directly from"
+                " apk.\n", fileName);
+            return INSTALL_FAILED_INVALID_APK;
+        }
+
+        if (!hasNativeBridge) {
+          return INSTALL_SUCCEEDED;
+        }
     }
 
     // Build local file path
@@ -208,6 +231,9 @@
     }
 
     // Only copy out the native file if it's different.
+    struct tm t;
+    ZipUtils::zipTimeToTimespec(when, &t);
+    modTime = mktime(&t);
     struct stat64 st;
     if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
         return INSTALL_SUCCEEDED;
@@ -465,10 +491,12 @@
 
 static jint
 com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
-        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi)
+        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
+        jboolean extractNativeLibs, jboolean hasNativeBridge)
 {
+    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
     return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi,
-            copyFileIfChanged, &javaNativeLibPath);
+            copyFileIfChanged, reinterpret_cast<void*>(args));
 }
 
 static jlong
@@ -548,7 +576,7 @@
             "(J)V",
             (void *)com_android_internal_content_NativeLibraryHelper_close},
     {"nativeCopyNativeBinaries",
-            "(JLjava/lang/String;Ljava/lang/String;)I",
+            "(JLjava/lang/String;Ljava/lang/String;ZZ)I",
             (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
     {"nativeSumNativeBinaries",
             "(JLjava/lang/String;)J",
diff --git a/core/res/res/color/date_picker_header_text_material.xml b/core/res/res/color/date_picker_header_text_material.xml
index cda894b..baa8958 100644
--- a/core/res/res/color/date_picker_header_text_material.xml
+++ b/core/res/res/color/date_picker_header_text_material.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_selected="true"
+        android:state_activated="true"
         android:color="?attr/textColorPrimaryInverse" />
     <item
         android:color="?attr/textColorSecondaryInverse" />
diff --git a/core/res/res/drawable/pointer_arrow_icon.xml b/core/res/res/drawable/pointer_arrow_icon.xml
index 8f7d658..72af0c1 100644
--- a/core/res/res/drawable/pointer_arrow_icon.xml
+++ b/core/res/res/drawable/pointer_arrow_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_arrow"
-    android:hotSpotX="6dp"
-    android:hotSpotY="6dp" />
+    android:hotSpotX="5dp"
+    android:hotSpotY="5dp" />
diff --git a/core/res/res/layout-land/date_picker_holo.xml b/core/res/res/layout-land/date_picker_holo.xml
deleted file mode 100644
index 991888c..0000000
--- a/core/res/res/layout-land/date_picker_holo.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="@dimen/datepicker_view_animator_height"
-              android:gravity="center"
-              android:orientation="horizontal"
-              android:minWidth="@dimen/datepicker_dialog_width" >
-
-    <include
-        layout="@layout/date_picker_selected_date"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1" />
-
-    <include layout="@layout/date_picker_view_animator" />
-
-</LinearLayout>
diff --git a/core/res/res/layout-land/date_picker_material.xml b/core/res/res/layout-land/date_picker_material.xml
new file mode 100644
index 0000000..1e711c5
--- /dev/null
+++ b/core/res/res/layout-land/date_picker_material.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="horizontal">
+
+    <include
+        layout="@layout/date_picker_header_material"
+        android:layout_width="168dp"
+        android:layout_height="match_parent" />
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+        <include
+            layout="@layout/date_picker_view_animator_material"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+        <ViewStub
+            android:id="@id/buttonPanel"
+            android:layout="@layout/alert_dialog_button_bar_material"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/day_picker_button_margin_top" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout-watch/progress_dialog_material.xml b/core/res/res/layout-watch/progress_dialog_material.xml
new file mode 100644
index 0000000..228f724
--- /dev/null
+++ b/core/res/res/layout-watch/progress_dialog_material.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:id="@+id/body"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:baselineAligned="false"
+        android:paddingStart="?attr/dialogPreferredPadding"
+        android:paddingTop="@dimen/dialog_padding_top_material"
+        android:paddingEnd="?attr/dialogPreferredPadding"
+        android:paddingBottom="@dimen/dialog_padding_top_material">
+
+        <ProgressBar
+            android:id="@id/progress"
+            style="?android:attr/progressBarStyleSmall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:max="10000"
+            android:layout_marginEnd="?attr/dialogPreferredPadding" />
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical" />
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/alert_dialog_button_bar_material.xml b/core/res/res/layout/alert_dialog_button_bar_material.xml
index 891bcd5..1eea4e1 100644
--- a/core/res/res/layout/alert_dialog_button_bar_material.xml
+++ b/core/res/res/layout/alert_dialog_button_bar_material.xml
@@ -18,16 +18,16 @@
 <com.android.internal.widget.ButtonBarLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/buttonPanel"
-    style="?attr/buttonBarStyle"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layoutDirection="locale"
     android:orientation="horizontal"
     android:paddingStart="12dp"
     android:paddingEnd="12dp"
-    android:paddingTop="8dp"
-    android:paddingBottom="8dp"
-    android:gravity="bottom">
+    android:paddingTop="4dp"
+    android:paddingBottom="4dp"
+    android:gravity="bottom"
+    style="?attr/buttonBarStyle">
 
     <Button
         android:id="@+id/button3"
diff --git a/core/res/res/layout/date_picker_header_material.xml b/core/res/res/layout/date_picker_header_material.xml
new file mode 100644
index 0000000..bda7de9
--- /dev/null
+++ b/core/res/res/layout/date_picker_header_material.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:id="@+id/date_picker_header"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:paddingBottom="18dp"
+              android:paddingStart="?attr/dialogPreferredPadding"
+              android:paddingEnd="?attr/dialogPreferredPadding"
+              android:orientation="vertical"
+              tools:background="@color/accent_material_light"
+              tools:paddingStart="24dp"
+              tools:paddingEnd="24dp">
+
+    <!-- Top padding should stay on this view so that
+         the touch target is a bit larger. -->
+    <TextView
+        android:id="@+id/date_picker_header_year"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="16dp"
+        android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel"
+        tools:text="2015"
+        tools:textSize="@dimen/date_picker_year_label_size"
+        tools:textColor="@color/white" />
+
+    <TextView
+        android:id="@+id/date_picker_header_date"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.Material.DatePicker.DateLabel"
+        android:maxLines="2"
+        android:ellipsize="none"
+        tools:text="Thu, Sep 30"
+        tools:textSize="@dimen/date_picker_date_label_size"
+        tools:textColor="@color/white" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_material.xml
similarity index 72%
rename from core/res/res/layout/date_picker_holo.xml
rename to core/res/res/layout/date_picker_material.xml
index 72030ea..a1c97ff 100644
--- a/core/res/res/layout/date_picker_holo.xml
+++ b/core/res/res/layout/date_picker_material.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2011 The Android Open Source Project
+     Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,17 +14,21 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="@dimen/datepicker_component_width"
+              android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:gravity="center"
               android:orientation="vertical">
 
     <include
-        layout="@layout/date_picker_selected_date"
+        layout="@layout/date_picker_header_material"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <include layout="@layout/date_picker_view_animator" />
+    <include
+        layout="@layout/date_picker_view_animator_material"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
 
 </LinearLayout>
diff --git a/core/res/res/layout/date_picker_selected_date.xml b/core/res/res/layout/date_picker_selected_date.xml
deleted file mode 100644
index 9becb81..0000000
--- a/core/res/res/layout/date_picker_selected_date.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/day_picker_selector_layout"
-    android:layout_width="@dimen/datepicker_component_width"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/date_picker_header"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/datepicker_header_height"
-        android:gravity="center"
-        android:importantForAccessibility="no" />
-
-    <LinearLayout
-        android:id="@+id/date_picker_month_day_year_layout"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp"
-        android:orientation="vertical"
-        android:gravity="center">
-
-        <LinearLayout
-            android:id="@+id/date_picker_month_and_day_layout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:clickable="true"
-            android:orientation="vertical">
-
-            <TextView
-                android:id="@+id/date_picker_month"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:duplicateParentState="true"
-                android:gravity="center" />
-
-            <TextView
-                android:id="@+id/date_picker_day"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="-23dp"
-                android:layout_marginBottom="-20dp"
-                android:duplicateParentState="true"
-                android:gravity="center" />
-        </LinearLayout>
-
-        <TextView
-            android:id="@+id/date_picker_year"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center" />
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/core/res/res/layout/date_picker_view_animator.xml b/core/res/res/layout/date_picker_view_animator.xml
deleted file mode 100644
index 9085ed5..0000000
--- a/core/res/res/layout/date_picker_view_animator.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
--->
-<com.android.internal.widget.AccessibleDateAnimator
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/animator"
-        android:layout_width="@dimen/datepicker_component_width"
-        android:layout_height="@dimen/datepicker_view_animator_height"
-        android:gravity="center" />
\ No newline at end of file
diff --git a/core/res/res/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
new file mode 100644
index 0000000..98ef1dd
--- /dev/null
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/animator"
+    android:layout_width="match_parent"
+    android:layout_height="0dp"
+    android:layout_weight="1"
+    android:gravity="center">
+
+    <android.widget.DayPickerView
+        android:id="@+id/date_picker_day_picker"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingStart="@dimen/day_picker_padding_horizontal"
+        android:paddingEnd="@dimen/day_picker_padding_horizontal"
+        android:paddingTop="@dimen/day_picker_padding_top" />
+
+    <android.widget.YearPickerView
+        android:id="@+id/date_picker_year_picker"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</ViewAnimator>
diff --git a/core/res/res/layout/year_label_text_view.xml b/core/res/res/layout/year_label_text_view.xml
index e5bd068..6240c4b 100644
--- a/core/res/res/layout/year_label_text_view.xml
+++ b/core/res/res/layout/year_label_text_view.xml
@@ -13,10 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<android.widget.TextViewWithCircularIndicator
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/month_text_view"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/datepicker_year_label_height"
-        android:layout_gravity="center"
-        android:gravity="center" />
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+         android:id="@+id/month_text_view"
+         android:layout_width="match_parent"
+         android:layout_height="wrap_content"
+         android:minHeight="?attr/listPreferredItemHeightSmall"
+         android:paddingTop="12dp"
+         android:paddingBottom="12dp"
+         android:gravity="center" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5400752..0c61591 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Vliegtuigmodus is AAN"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Vliegtuigmodus is AF"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Instellings"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Help"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Stembystand"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5e55c41..b639b4f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"ደግፍ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1ccea6d..42bf57d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -207,6 +207,7 @@
     <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_assist" msgid="3892832961594295030">"مساعدة"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"المساعد الصوتي"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 8bc76c4..ecfa7bd 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Банерът за роуминг е включен"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Банерът за роуминг е изключен"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Търси се покритие"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Обаждания през Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Не е пренасочено"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Помощ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заключване сега"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Има достъпна отворена Wi-Fi мрежа</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Влизане в Wi-Fi мрежа"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не можа да се свърже с Wi-Fi"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 650f1c3..f20e21f 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"রোমিং ব্যানার চালু আছে"</string>
     <string name="roamingText12" msgid="1189071119992726320">"রোমিং ব্যানার বন্ধ আছে"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"পরিষেবা অনুসন্ধান করা হচ্ছে"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi কলিং"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফরওয়ার্ড করা হয়নি"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"সহযোগিতা"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"এখনই লক করুন"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="one">খোলা Wi-Fi নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
       <item quantity="other">খোলা Wi-Fi নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi নেটওয়ার্কে সাইন ইন করুন"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে সাইন ইন করুন"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi এর সাথে সংযোগ করা যায়নি"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index de1c6ae..aebebf2 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Bàner d\'itinerància activat"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Bàner d\'itinerància desactivat"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"S\'està cercant el servei"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Trucades per Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no s\'ha desviat"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode d\'avió activat"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode d\'avió desactivat"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Configuració"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistència"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. per veu"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Xarxa Wi-Fi oberta disponible</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia la sessió a la xarxa Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No s\'ha pogut connectar a la Wi-Fi"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 778d0fe..988818b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -125,8 +125,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Banner roamingu je zapnutý"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Banner roamingu je vypnutý"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volání přes Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepřesměrováno"</string>
@@ -206,6 +205,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim Letadlo je ZAPNUTÝ"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim Letadlo je VYPNUTÝ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Nastavení"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asistence"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlas. asistence"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1316,8 +1316,7 @@
       <item quantity="one">K dispozici je veřejná síť Wi-Fi</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Přihlásit se k síti Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Připojení k síti Wi-Fi se nezdařilo"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9077a83..20b7ad2 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flytilstand er TIL"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flytilstand er slået FRA"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Indstillinger"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistance"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3bafcc8..07153fe 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Roaming-Banner ein"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Roaming-Banner aus"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Suche nach Dienst"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN-Telefonie"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nicht weitergeleitet"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flugmodus ist AN."</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flugmodus ist AUS."</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Einstellungen"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Geräteassistent"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Verfügbares WLAN-Netzwerk öffnen</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN-Netzwerk anmelden"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Es konnte keine WLAN-Verbindung hergestellt werden."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 02b21ec..e0a6f88 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Βοήθεια"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Φων.υποβοηθ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-en-rAU-watch/strings.xml b/core/res/res/values-en-rAU-watch/strings.xml
new file mode 100644
index 0000000..6734cd3
--- /dev/null
+++ b/core/res/res/values-en-rAU-watch/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="android_upgrading_apk" msgid="1090732262010398759">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..f52daf6
--- /dev/null
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -0,0 +1,1847 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="byteShort" msgid="8340973892742019101">"B"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
+    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hrs"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> mins"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> hr <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> mins"</string>
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> secs"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
+    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> secs"</string>
+    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sec"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
+    <string name="unknownName" msgid="6867811765370350269">"Unknown"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Connection problem or invalid MMI code."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Operation is restricted to fixed dialling numbers only."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Service was enabled."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Service was enabled for:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Service has been disabled."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Registration was successful."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Erase successful."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Incorrect password."</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI complete."</string>
+    <string name="badPin" msgid="9015277645546710014">"The old PIN that you typed is incorrect."</string>
+    <string name="badPuk" msgid="5487257647081132201">"The PUK that you typed isn\'t correct."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"The PINs that you typed don\'t match."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Type a PUK that is 8 numbers or longer."</string>
+    <string name="needPuk" msgid="919668385956251611">"Your SIM card is PUK-locked. Type the PUK code to unlock it."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Type PUK2 to unblock SIM card."</string>
+    <string name="enablePin" msgid="209412020907207950">"Unsuccessful, enable SIM/RUIM Lock."</string>
+    <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
+      <item quantity="other">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="one">You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM is locked.</item>
+    </plurals>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Outgoing Caller ID"</string>
+    <string name="ColpMmi" msgid="3065121483740183974">"Connected Line ID"</string>
+    <string name="ColrMmi" msgid="4996540314421889589">"Connected Line ID Restriction"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Call forwarding"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Call waiting"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Call barring"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Password change"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PIN change"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Calling number present"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Calling number restricted"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Three-way calling"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Rejection of undesired annoying calls"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Do not disturb"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Caller ID defaults to restricted. Next call: Restricted"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Caller ID defaults to restricted. Next call: Not restricted"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Caller ID defaults to not restricted. Next call: Restricted"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Caller ID defaults to not restricted. Next call: Not restricted"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Restricted access changed"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Data service is blocked."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Emergency service is blocked."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Voice service is blocked."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"All voice services are blocked."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS service is blocked."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Voice/Data services are blocked."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Voice/SMS services are blocked."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"All voice/data/SMS services are blocked."</string>
+    <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer requested TTY Mode FULL"</string>
+    <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer requested TTY Mode HCO"</string>
+    <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer requested TTY Mode VCO"</string>
+    <string name="peerTtyModeOff" msgid="3280819717850602205">"Peer requested TTY Mode OFF"</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Voice"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Data"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sync"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Packet"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Roaming Indicator On"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Roaming Indicator Off"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Roaming Indicator Flashing"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Out of local area"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Out of Building"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Roaming - Preferred System"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Roaming - Available System"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Roaming - Alliance Partner"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Roaming - Premium Partner"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Roaming - Full Service Functionality"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - Partial Service Functionality"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner On"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Roaming Banner Off"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
+  <string-array name="wfcOperatorErrorMessages">
+  </string-array>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</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> after <xliff:g id="TIME_DELAY">{2}</xliff:g> seconds"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Feature code complete."</string>
+    <string name="fcError" msgid="3327560126588500777">"Connection problem or invalid feature code."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"There was a network error."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"Couldn\'t find the URL."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"The site authentication scheme isn\'t supported."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Couldn\'t authenticate."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Authentication via the proxy server was unsuccessful."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Couldn\'t connect to the server."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Couldn\'t communicate with the server. Try again later."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"The connection to the server timed out."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"The page contains too many server redirects."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"The protocol isn\'t supported."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Couldn\'t establish a secure connection."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Couldn\'t open the page because the URL is invalid."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Couldn\'t access the file."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Couldn\'t find the requested file."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Too many requests are being processed. Try again later."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Sign-in error for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sync"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sync"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Too many <xliff:g id="CONTENT_TYPE">%s</xliff:g> deletions."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"Watch storage is full. Delete some files to free up space."</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"TV storage is full. Delete some files to free space."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"By an unknown third party"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"By your work profile administrator"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"By <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
+    <string name="work_profile_deleted" msgid="5005572078641980632">"Work profile deleted"</string>
+    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Work profile deleted due to missing admin app."</string>
+    <string name="work_profile_deleted_details" msgid="226615743462361248">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your administrator for assistance."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"Your device will be erased"</string>
+    <string name="factory_reset_message" msgid="4905025204141900666">"The admin app is missing components or corrupted, and can\'t be used. Your device will now be erased. Contact your administrator for assistance."</string>
+    <string name="me" msgid="6545696007631404292">"Me"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
+    <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV options"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Silent mode"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Turn on wireless"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Turn off wireless"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Screen lock"</string>
+    <string name="power_off" msgid="4266614107412865048">"Power off"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Ringer off"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Ringer vibrate"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Ringer on"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Shutting down…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Your tablet will shut down."</string>
+    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Your TV will shut down."</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Your watch will shut down."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Your phone will shut down."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Do you want to shut down?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Reboot to safe mode"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Do you want to reboot into safe mode? This will disable all third-party applications that you have installed. They will be restored when you reboot again."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"No recent apps"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet options"</string>
+    <string name="global_actions" product="tv" msgid="7240386462508182976">"TV options"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Phone options"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Screen lock"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Power off"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Aeroplane mode"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
+    <string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assist"</string>
+    <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
+    <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
+    <string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services that cost you money"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Do things that can cost you money."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Your messages"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Read and write your SMS, email and other messages."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Your personal information"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Direct access to information about you, stored in on your contact card."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Your location"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitor your physical location."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Network communication"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Access various network features."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Access devices and networks through Bluetooth."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio Settings"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Change audio settings."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Affects Battery"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Use features that can quickly drain battery."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direct access to calendar and events."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Read User Dictionary"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Read words in user dictionary."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Write User Dictionary"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Add words to the user dictionary."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Set the alarm clock."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Voicemail"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Direct access to voicemail."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Direct access to the microphone to record audio."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Direct access to camera for image or video capture."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Lock screen"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Ability to affect behaviour of the lock screen on your device."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Your applications information"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Ability to affect behaviour of other applications on your device."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Wallpaper"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Change the device wallpaper settings."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Clock"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Change the device time or timezone."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Status Bar"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Change the device status bar settings."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sync Settings"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Access to the sync settings."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Your accounts"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access the available accounts."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware controls"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direct access to hardware on the handset."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Phone calls"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Monitor, record and process phone calls."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"System tools"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Lower-level access and control of the system."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Development tools"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Features only needed for app developers."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Other Application UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Effect the UI of other applications."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Access the USB storage."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Access the SD card."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Accessibility features"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Features that assistive technology can request."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Touched items will be spoken aloud and the screen can be explored using gestures."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Turn on enhanced web accessibility"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Scripts may be installed to make app content more accessible."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observe text that you type"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"status bar"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Allows the app to be the status bar."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"expand/collapse status bar"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_install_shortcut" msgid="4279070216371564234">"install shortcuts"</string>
+    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Allows an application to add Home screen shortcuts without user intervention."</string>
+    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uninstall shortcuts"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Allows the application to remove Home screen shortcuts without user intervention."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"reroute outgoing calls"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Allows the app to see the number being dialled during an outgoing call with the option to redirect the call to a different number or abort the call altogether."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"receive text messages (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"receive emergency broadcasts"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Allows the app to receive and process emergency broadcast messages. This permission is only available for system apps."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"send SMS messages"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Allows the app to send SMS messages. This may result in unexpected charges. Malicious apps may cost you money by sending messages without your confirmation."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"send respond-via-message events"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Allows the app to send requests to other messaging apps to handle respond-via-message events for incoming calls."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"read your text messages (SMS or MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Allows the app to read SMS messages stored on your tablet or SIM card. This allows the app to read all SMS messages, regardless of content or confidentiality."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Allows the app to read SMS messages stored on your TV or SIM card. This allows the app to read all SMS messages, regardless of content or confidentiality."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Allows the app to read SMS messages stored on your phone or SIM card. This allows the app to read all SMS messages, regardless of content or confidentiality."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"edit your text messages (SMS or MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Allows the app to write to SMS messages stored on your tablet or SIM card. Malicious apps may delete your messages."</string>
+    <string name="permdesc_writeSms" product="tv" msgid="955871498983538187">"Allows the app to write to SMS messages stored on your TV or SIM card. Malicious apps may delete your messages."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Allows the app to write to SMS messages stored on your phone or SIM card. Malicious apps may delete your messages."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"receive text messages (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Allows the app to receive and process WAP messages. This permission includes the ability to monitor or delete messages sent to you without showing them to you."</string>
+    <string name="permlab_receiveBluetoothMap" msgid="7593811487142360528">"receive Bluetooth messages (MAP)"</string>
+    <string name="permdesc_receiveBluetoothMap" msgid="8656755936919466345">"Allows the app to receive and process Bluetooth MAP messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"retrieve running apps"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Allows the app to retrieve information about currently and recently running tasks. This may allow the app to discover information about which applications are used on the device."</string>
+    <string name="permlab_startTasksFromRecents" msgid="8990073877885690623">"start a task from recents"</string>
+    <string name="permdesc_startTasksFromRecents" msgid="7382133554871222235">"Allows the app to use an ActivityManager.RecentTaskInfo object to launch a defunct task that was returned from ActivityManager.getRecentTaskList()."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interact across users"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Allows the app to perform actions across different users on the device. Malicious apps may use this to violate the protection between users."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full license to interact across users"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Allows all possible interactions across users."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"manage users"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Allows apps to manage users on the device, including query, creation and deletion."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"retrieve details of running apps"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Allows the app to retrieve detailed information about currently and recently running tasks. Malicious apps may discover private information about other apps."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"re-order running apps"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Allows the app to move tasks to the foreground and background. The app may do this without your input."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"stop running apps"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Allows the app to remove tasks and kill their apps. Malicious apps may disrupt the behaviour of other apps."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"manage activity stacks"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Allows the app to add, remove and modify the activity stacks in which other apps run. Malicious apps may disrupt the behaviour of other apps."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"start any activity"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Allows the app to start any activity, regardless of permission protection or exported state."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"set screen compatibility"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Allows the app to control the screen compatibility mode of other applications. Malicious applications may break the behaviour of other applications."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"enable app debugging"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Allows the app to turn on debugging for another app. Malicious apps may use this to kill other apps."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"change system display settings"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Allows the app to change the current configuration, such as the locale or overall font size."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"enable car mode"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Allows the app to enable the car mode."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"close other apps"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Allows the app to end background processes of other apps. This may cause other apps to stop running."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"force stop other apps"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Allows the app to forcibly stop other apps."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"force app to close"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Allows the app to force any activity that is in the foreground to close and go back. Should never be needed for normal apps."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"retrieve system internal status"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Allows the app to retrieve the internal state of the system. Malicious apps may retrieve a wide variety of private and secure information that they should never normally need."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"retrieve screen content"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Allows the app to retrieve the content of the active window. Malicious apps may retrieve the entire window content and examine all its text except passwords."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"temporary enable accessibility"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Allows an application to temporarily enable accessibility on the device. Malicious apps may enable accessibility without user consent."</string>
+    <string name="permlab_retrieveWindowToken" msgid="7154762602367758602">"retrieve window token"</string>
+    <string name="permdesc_retrieveWindowToken" msgid="668173747687795074">"Allows an application to retrieve the window token. Malicious apps may perform unauthorised interaction with the application window impersonating the system."</string>
+    <string name="permlab_frameStats" msgid="7056374987314361639">"retrieve frame statistics"</string>
+    <string name="permdesc_frameStats" msgid="4758001089491284919">"Allows an application to collect frame statistics. Malicious apps may observe the frame statistics of windows from other apps."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filter events"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Allows an application to register an input filter which filters the stream of all user events before they are dispatched. Malicious app may control the system UI without user intervention."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"partial shutdown"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Puts the activity manager into a shut-down state. Does not perform a complete shut down."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"prevent app switches"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Prevents the user from switching to another app."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"get current app info"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Allows the holder to retrieve private information about the current application in the foreground of the screen."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitor and control all app launching"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Allows the app to monitor and control how the system launches activities. Malicious apps may completely compromise the system. This permission is only needed for development, never for normal use."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"send package removed broadcast"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Allows the app to broadcast a notification that an app package has been removed. Malicious apps may use this to kill any other running app."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"send SMS-received broadcast"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Allows the app to broadcast a notification that an SMS message has been received. Malicious apps may use this to forge incoming SMS messages."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"send WAP-PUSH-received broadcast"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Allows the app to broadcast a notification that a WAP PUSH message has been received. Malicious apps may use this to forge MMS message receipt or to silently replace the content of any web page with malicious variants."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"limit number of running processes"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Allows the app to control the maximum number of processes that will run. Never needed for normal apps."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"force background apps to close"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Allows the app to control whether activities are always finished as soon as they go to the background. Never needed for normal apps."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"read battery statistics"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Allows an application to read the current low-level battery use data. May allow the application to find out detailed information about which apps you use."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"modify battery statistics"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Allows the app to modify collected battery statistics. Not for use by normal apps."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"retrieve app ops statistics"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Allows the app to retrieve collected application operation statistics. Not for use by normal apps."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modify app ops statistics"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Allows the app to modify collected component usage statistics. Not for use by normal apps."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"control system back up and restore"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Allows the app to control the system\'s backup and restore mechanism. Not for use by normal apps."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"confirm a full backup or restore operation"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Allows the app to launch the full backup confirmation UI. Not to be used by any app."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"display unauthorised windows"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Allows the app to create windows that are intended to be used by the internal system user interface. Not for use by normal apps."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"draw over other apps"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Allows the app to draw on top of other applications or parts of the user interface. They may interfere with your use of the interface in any application, or change what you think you are seeing in other applications."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"modify global animation speed"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Allows the app to change the global animation speed (faster or slower animations) at any time."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"manage app tokens"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Allows the app to create and manage their own tokens, bypassing their normal Z-ordering. Should never be needed for normal apps."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"freeze screen"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Allows the application to temporarily freeze the screen for a full-screen transition."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"press keys and control buttons"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Allows the app to deliver its own input events (key presses, etc.) to other apps. Malicious apps may use this to take over the tablet."</string>
+    <string name="permdesc_injectEvents" product="tv" msgid="4681361983270791611">"Allows the app to deliver its own input events (key presses, etc.) to other apps. Malicious apps may use this to take over the TV."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Allows the app to deliver its own input events (key presses, etc.) to other apps. Malicious apps may use this to take over the phone."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"record what you type and actions that you take"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Allows the app to watch the keys that you press even when interacting with another app (such as typing a password). Should never be needed for normal apps."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"bind to an input method"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal apps."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind to an accessibility service"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind to a VPN service"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Allows the holder to bind to the top-level interface of a Vpn service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind to wallpaper"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Allows the holder to bind to the top-level interface of wallpaper. Should never be needed for normal applications."</string>
+    <string name="permlab_bindVoiceInteraction" msgid="5334852580713715068">"bind to a voice interactor"</string>
+    <string name="permdesc_bindVoiceInteraction" msgid="2345721766501778101">"Allows the holder to bind to the top-level interface of a voice interaction service. Should never be needed for normal apps."</string>
+    <string name="permlab_manageVoiceKeyphrases" msgid="1252285102392793548">"manage voice key phrases"</string>
+    <string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"Allows the holder to manage the key phrases for voice hotword detection. Should never be needed for normal apps."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"bind to a remote display"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Allows the holder to bind to the top-level interface of a remote display. Should never be needed for normal apps."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"bind to a route provider service"</string>
+    <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"Allows the holder to bind to any registered route providers. Should never be needed for normal apps."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Allows the holder to send intents to a device administrator. Should never be needed for normal apps."</string>
+    <string name="permlab_bindTvInput" msgid="5601264742478168987">"bind to a TV input"</string>
+    <string name="permdesc_bindTvInput" msgid="2371008331852001924">"Allows the holder to bind to the top-level interface of a TV input. Should never be needed for normal apps."</string>
+    <string name="permlab_modifyParentalControls" msgid="4611318225997592242">"modify parental controls"</string>
+    <string name="permdesc_modifyParentalControls" msgid="7438482894162282039">"Allows the holder to modify the system\'s parental controls data. Should never be needed for normal apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"add or remove a device admin"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Allows the holder to add or remove active device administrators. Should never be needed for normal apps."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"change screen orientation"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Allows the app to change the rotation of the screen at any time. Should never be needed for normal apps."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"change pointer speed"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Allows the app to change the mouse or touch pad pointer speed at any time. Should never be needed for normal apps."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"change keyboard layout"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Allows the app to change the keyboard layout. Should never be needed for normal apps."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"send Linux signals to apps"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Allows the app to request that the supplied signal be sent to all persistent processes."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"make app always run"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the tablet."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the TV."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the phone."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"delete apps"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Allows the app to delete Android packages. Malicious apps may use this to delete important apps."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"delete other apps\' data"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Allows the app to clear user data."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"delete other apps\' caches"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Allows the app to delete cache files."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"measure app storage space"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Allows the app to retrieve its code, data and cache sizes"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"directly install apps"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Allows the app to install new or updated Android packages. Malicious apps may use this to add new apps with arbitrarily powerful permissions."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"delete all app cache data"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Allows the app to free tablet storage by deleting files in the cache directories of other applications. This may cause other applications to start up more slowly as they need to re-retrieve their data."</string>
+    <string name="permdesc_clearAppCache" product="tv" msgid="244647416303997022">"Allows the app to free TV storage by deleting files in the cache directories of other applications. This may cause other applications to start up more slowly as they need to re-retrieve their data."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Allows the app to free phone storage by deleting files in the cache directories of other applications. This may cause other applications to start up more slowly as they need to re-retrieve their data."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"move app resources"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Allows the app to move app resources from internal to external media and vice versa."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"read sensitive log data"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the tablet, potentially including personal or private information."</string>
+    <string name="permdesc_readLogs" product="tv" msgid="9023899974809538988">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the TV, potentially including personal or private information."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the phone, potentially including personal or private information."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"use any media decoder for playback"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
+    <string name="permlab_bindJobService" msgid="3637568367978271086">"run the application\'s scheduled background work"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"This permission allows the Android system to run the application in the background when requested."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important tablet capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+    <string name="permdesc_changeComponentState" product="tv" msgid="9151634188264231389">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important TV capabilities. Care must be used with this permission, as it is possible for app components to become unusable, inconsistent, or unstable."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important phone capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"grant or revoke permissions"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Allows an application to grant or revoke specific permissions for it or other applications. Malicious applications may use this to access features for which you have not granted them permission."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"set preferred apps"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Allows the app to modify your preferred apps. Malicious apps may silently change the apps that are run, spoofing your existing apps to collect private data from you."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"modify system settings"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Allows the app to modify the system\'s settings data. Malicious apps may corrupt your system\'s configuration."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modify secure system settings"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Allows the app to modify the system\'s secure settings data. Not for use by normal apps."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"modify the Google services map"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Allows the app to modify the Google services map. Not for use by normal apps."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"run at startup"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the tablet and allow the app to slow down the overall tablet by always running."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the TV and allow the app to slow down the overall tablet by always running."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the phone and allow the app to slow down the overall phone by always running."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"send sticky broadcast"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the tablet slow or unstable by causing it to use too much memory."</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the TV slow or unstable by causing it to use too much memory."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"read your contacts"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Allows the app to read data about your contacts stored on your TV, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"modify your contacts"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Allows the app to modify the data about your contacts stored on your TV, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"read call log"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Allows the app to read your tablet\'s call log, including data about incoming and outgoing calls. This permission allows apps to save your call log data, and malicious apps may share call log data without your knowledge."</string>
+    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Allows the app to read your TV\'s call log, including data about incoming and outgoing calls. This permission allows apps to save your call log data, and malicious apps may share call log data without your knowledge."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Allows the app to read your phone\'s call log, including data about incoming and outgoing calls. This permission allows apps to save your call log data, and malicious apps may share call log data without your knowledge."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"write call log"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"read your own contact card"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Allows the app to read personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
+    <string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Allows the app to access and sync social updates from you and your friends. Be careful when sharing information - this allows the app to read communications between you and your friends on social networks, regardless of confidentiality. Note: this permission may not be enforced on all social networks."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Allows the app to display social updates from your friends. Be careful when sharing information - this allows the app to produce messages that may appear to come from a friend. Note: this permission may not be enforced on all social networks."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Allows the app to read all calendar events stored on your tablet, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Allows the app to read all calendar events stored on your TV, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Allows the app to read all calendar events stored on your phone, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"add or modify calendar events and send emails to guests without owners\' knowledge"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Allows the app to add, remove and change events that you can modify on your tablet, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Allows the app to add, remove, change events that you can modify on your TV, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Allows the app to add, remove and change events that you can modify on your phone, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"mock location sources for testing"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"permission to install a location provider"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"precise location (GPS and network-based)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Allows the app to get your precise location using the Global Positioning System (GPS) or network location sources such as mobile towers and Wi-Fi. These location services must be turned on and available to your device for the app to use them. Apps may use this to determine where you are, and may consume additional battery power."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"approximate location (network-based)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Allows the app to get your approximate location. This location is derived by location services using network location sources such as mobile towers and Wi-Fi. These location services must be turned on and available to your device for the app to use them. Apps may use this to determine approximately where you are."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"access SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Allows the app to use SurfaceFlinger low-level features."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"read frame buffer"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Allows the app to read the content of the frame buffer."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"access InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configure Wi-Fi displays"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
+    <string name="permlab_controlVpn" msgid="2618442789397588200">"control Virtual Private Networks"</string>
+    <string name="permdesc_controlVpn" msgid="762852603315861214">"Allows the app to control low-level features of Virtual Private Networks."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capture audio output"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Allows the app to capture and redirect audio output."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword detection"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Allows the app to capture audio for Hotword detection. The capture can happen in the background but does not prevent other audio capture (e.g. Camcorder)."</string>
+    <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"Audio Routing"</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Allows the app to directly control audio routing and override audio policy decisions."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capture video output"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Allows the app to capture and redirect video output."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capture secure video output"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Allows the app to capture and redirect secure video output."</string>
+    <string name="permlab_mediaContentControl" msgid="8749790560720562511">"control media playback and metadata access"</string>
+    <string name="permdesc_mediaContentControl" msgid="1637478200272062">"Allows the app to control media playback and access the media information (title, author...)."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"record audio"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Allows the app to record audio with the microphone. This permission allows the app to record audio at any time without your confirmation."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM communication"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Allows the app to send commands to the SIM. This is very dangerous."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"take pictures and videos"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Allows the app to take pictures and videos with the camera. This permission allows the app to use the camera at any time without your confirmation."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"disable transmit indicator LED when camera is in use"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Allows a pre-installed system application to disable the camera use indicator LED."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"permanently disable tablet"</string>
+    <string name="permlab_brick" product="tv" msgid="4912674222121249410">"permanently disable TV"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"permanently disable phone"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Allows the app to permanently disable the entire tablet. This is very dangerous."</string>
+    <string name="permdesc_brick" product="tv" msgid="7070924544316356349">"Allows the app to disable the entire TV permanently. This is very dangerous."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Allows the app to permanently disable the entire phone. This is very dangerous."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"force tablet reboot"</string>
+    <string name="permlab_reboot" product="tv" msgid="2112102119558886236">"force TV reboot"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"force phone reboot"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Allows the app to force the tablet to reboot."</string>
+    <string name="permdesc_reboot" product="tv" msgid="7116222694344401650">"Allows the app to force the TV to reboot."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Allows the app to force the phone to reboot."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"access USB storage filesystem"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"access SD Card filesystem"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Allows the app to mount and unmount file systems for removable storage."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"Erase USB storage"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"erase SD Card"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Allows the app to format removable storage."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"get information on internal storage"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Allows the application to access information on internal storage."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"create internal storage"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Allows the application to create internal storage."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"destroy internal storage"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Allows the app to destroy internal storage."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"mount/unmount internal storage"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Allows the app to mount/unmount internal storage."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"rename internal storage"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Allows the app to rename internal storage."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"control vibration"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Allows the app to control the vibrator."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"control flashlight"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Allows the app to control the flashlight."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"manage preferences and permissions for USB devices"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Allows the app to manage preferences and permissions for USB devices."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"implement MTP protocol"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Allows access to the kernel MTP driver to implement the MTP USB protocol."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"test hardware"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Allows the app to control various peripherals for the purpose of hardware testing."</string>
+    <string name="permlab_fm" msgid="8749504526866832">"access FM radio"</string>
+    <string name="permdesc_fm" msgid="4145699441237962818">"Allows the app to access FM radio to listen to programmes."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"directly call any phone numbers"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Allows the app to call any phone number, including emergency numbers, without your intervention. Malicious apps may place unnecessary and illegal calls to emergency services."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"directly start CDMA tablet setup"</string>
+    <string name="permlab_performCdmaProvisioning" product="tv" msgid="3485391974208100809">"directly start CDMA TV setup"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"directly start CDMA phone setup"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Allows the app to start CDMA provisioning. Malicious apps may unnecessarily start CDMA provisioning."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"control location update notifications"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Allows the app to enable/disable location update notifications from the radio. Not for use by normal apps."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"access check-in properties"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Allows the app read/write access to properties uploaded by the check-in service. Not for use by normal apps."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"choose widgets"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Allows the app to tell the system which widgets can be used by which app. An app with this permission can give other apps access to personal data. Not for use by normal apps."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modify phone status"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Allows the app to control the phone features of the device. An app with this permission can switch networks, turn the phone radio on and off and the like without ever notifying you."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"read precise phone states"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Allows the app to access the precise phone states. This permission allows the app to determine the real call status, whether a call is active or in the background, call fails, precise data connection status and data connection fails."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
+    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"prevent TV from sleeping"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Allows the app to prevent the TV from going to sleep."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Allows the app to prevent the phone from going to sleep."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmit infrared"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Allows the app to use the tablet\'s infrared transmitter."</string>
+    <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Allows the app to use the TV\'s infrared transmitter."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Allows the app to use the phone\'s infrared transmitter."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"turn tablet on or off"</string>
+    <string name="permlab_devicePower" product="tv" msgid="7579718349658943416">"power TV on or off"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"turn phone on or off"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Allows the app to turn the tablet on or off."</string>
+    <string name="permdesc_devicePower" product="tv" msgid="1334908641773273512">"Allows the app to turn the TV on or off."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Allows the app to turn the phone on or off."</string>
+    <string name="permlab_userActivity" msgid="1677844893921729548">"reset display timeout"</string>
+    <string name="permdesc_userActivity" msgid="651746160252248024">"Allows the app to reset the display timeout."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"run in factory test mode"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Run as a low-level manufacturer test, allowing complete access to the tablet hardware. Only available when a tablet is running in manufacturer test mode."</string>
+    <string name="permdesc_factoryTest" product="tv" msgid="2105643629211155695">"Run as a low-level manufacturer test, allowing complete access to the TV hardware. Only available when a TV is running in manufacturer test mode."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Run as a low-level manufacturer test, allowing complete access to the phone hardware. Only available when a phone is running in manufacturer test mode."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"set wallpaper"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Allows the app to set the system wallpaper."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"adjust your wallpaper size"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Allows the app to set the system wallpaper size hints."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"reset system to factory defaults"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Allows the app to completely reset the system to its factory settings, erasing all data, configuration and installed apps."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"set time"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Allows the app to change the tablet\'s clock time."</string>
+    <string name="permdesc_setTime" product="tv" msgid="1826398919861882682">"Allows the app to change the TV\'s clock time."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Allows the app to change the phone\'s clock time."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"set time zone"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Allows the app to change the tablet\'s time zone."</string>
+    <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Allows the app to change the TV\'s time zone."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Allows the app to change the phone\'s time zone."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"act as the Account Manager Service"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Allows the app to make calls to Account Authenticators."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"find accounts on the device"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Allows the app to get the list of accounts known by the tablet. This may include any accounts created by applications that you have installed."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Allows the app to get the list of accounts known by the TV. This may include any accounts created by applications that you have installed."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Allows the app to get the list of accounts known by the phone. This may include any accounts created by applications that you have installed."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"create accounts and set passwords"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Allows the app to use the account authenticator capabilities of the Account Manager, including creating accounts and getting and setting their passwords."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"add or remove accounts"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Allows the app to perform operations like adding and removing accounts, and deleting their password."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"use accounts on the device"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Allows the app to request authentication tokens."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"view network connections"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Allows the app to view information about network connections such as which networks exist and are connected."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"full network access"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Allows the app to create network sockets and use customised network protocols. The browser and other applications provide means to send data to the Internet, so this permission is not required to send data to the Internet."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"change/intercept network settings and traffic"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Allows the app to change network settings and to intercept and inspect all network traffic, for example to change the proxy and port of any APN. Malicious apps may monitor, redirect or modify network packets without your knowledge."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"change network connectivity"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Allows the app to change the state of network connectivity."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"change tethered connectivity"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Allows the app to change the state of tethered network connectivity."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"change background data usage setting"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Allows the app to change the background data usage setting."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"view Wi-Fi connections"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Allows the app to view information about Wi-Fi networking, such as whether Wi-Fi is enabled and name of connected Wi-Fi devices."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"connect and disconnect from Wi-Fi"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Allows the app to connect to and disconnect from Wi-Fi access points and to make changes to device configuration for Wi-Fi networks."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"allow Wi-Fi Multicast reception"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your tablet. It uses more power than the non-multicast mode."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your TV. It uses more power than the non-multicast mode."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your phone. It uses more power than the non-multicast mode."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"access Bluetooth settings"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Allows the app to configure the local Bluetooth tablet and to discover and pair with remote devices."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Allows the app to configure the local Bluetooth TV, and to discover and pair with remote devices."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Allows the app to configure the local Bluetooth phone and to discover and pair with remote devices."</string>
+    <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"allow Bluetooth pairing by Application"</string>
+    <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"Allows the app to pair with remote devices without user interaction."</string>
+    <string name="permdesc_bluetoothPriv" product="tv" msgid="8045735193417468857">"Allows the app to pair with remote devices without user interaction."</string>
+    <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"Allows the app to pair with remote devices without user interaction."</string>
+    <string name="permlab_bluetoothMap" msgid="6372198338939197349">"access Bluetooth MAP data"</string>
+    <string name="permdesc_bluetoothMap" product="tablet" msgid="5784090105926959958">"Allows the app to access Bluetooth MAP data."</string>
+    <string name="permdesc_bluetoothMap" product="tv" msgid="5784090105926959958">"Allows the app to access Bluetooth MAP data."</string>
+    <string name="permdesc_bluetoothMap" product="default" msgid="5784090105926959958">"Allows the app to access Bluetooth MAP data."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"connect and disconnect from WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Allows the app to determine whether WiMAX is enabled and information about any WiMAX networks that are connected."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"change WiMAX state"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Allows the app to connect the tablet to and disconnect the tablet from WiMAX networks."</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Allows the app to connect the TV to and disconnect the TV from WiMAX networks."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Allows the app to connect the phone to and disconnect the phone from WiMAX networks."</string>
+    <string name="permlab_scoreNetworks" msgid="6445777779383587181">"score networks"</string>
+    <string name="permdesc_scoreNetworks" product="tablet" msgid="1304304745850215556">"Allows the app to rank networks and influence which networks the tablet should prefer."</string>
+    <string name="permdesc_scoreNetworks" product="tv" msgid="5444434643862417649">"Allows the app to rank networks and influence which networks the TV should prefer."</string>
+    <string name="permdesc_scoreNetworks" product="default" msgid="1831501848178651379">"Allows the app to rank networks and influence which networks the phone should prefer."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"pair with Bluetooth devices"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Allows the app to view the configuration of Bluetooth on the TV, and to make and accept connections with paired devices."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"control Near-Field Communication"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
+    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Allows the app to invoke methods to add and delete fingerprint templates for use."</string>
+    <string name="permlab_useFingerprint" msgid="3150478619915124905">"use fingerprint hardware"</string>
+    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Allows the app to use fingerprint hardware for authentication"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable syncing of the People app with an account."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"write subscribed feeds"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Allows the app to modify your currently synced feeds. Malicious apps may change your synced feeds."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"read terms you added to the dictionary"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Allows the app to read all words, names and phrases that the user may have stored in the user dictionary."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"add words to user-defined dictionary"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Allows the app to write new words into the user dictionary."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"read the contents of your USB storage"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"read the contents of your SD card"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Allows the app to read the contents of your USB storage."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Allows the app to read the contents of your SD card."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modify or delete the contents of your USB storage"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modify or delete the contents of your SD card"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Allows the app to write to the USB storage."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Allows the app to modify the contents of the internal media storage."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"manage document storage"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Allows the app to manage document storage."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"access external storage of all users"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Allows the app to access external storage for all users."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"access the cache file system"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Allows the app to read and write the cache file system."</string>
+    <string name="permlab_use_sip" msgid="2052499390128979920">"make/receive SIP calls"</string>
+    <string name="permdesc_use_sip" msgid="2297804849860225257">"Allows the app to make and receive SIP calls."</string>
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"register new telecom SIM connections"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Allows the app to register new telecom SIM connections."</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"register new telecom connections"</string>
+    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Allows the app to register new telecom connections."</string>
+    <string name="permlab_connection_manager" msgid="1116193254522105375">"manage telecom connections"</string>
+    <string name="permdesc_connection_manager" msgid="5925480810356483565">"Allows the app to manage telecom connections."</string>
+    <string name="permlab_bind_incall_service" msgid="6773648341975287125">"interact with in-call screen"</string>
+    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Allows the app to control when and how the user sees the in-call screen."</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"interact with telephony services"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Allows the app to interact with telephony services to make/receive calls."</string>
+    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"provide an in-call user experience"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Allows the app to provide an in-call user experience."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"read historical network usage"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Allows the app to read historical network usage for specific networks and apps."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"manage network policy"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Allows the app to manage network policies and define app-specific rules."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modify network usage accounting"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Allows the app to modify how network usage is accounted against apps. Not for use by normal apps."</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"access notifications"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Allows the app to retrieve, examine, and clear notifications, including those posted by other apps."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bind to a notification listener service"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindChooserTargetService" msgid="3443261076710185673">"bind to a chooser target service"</string>
+    <string name="permdesc_bindChooserTargetService" msgid="1413908999583734970">"Allows the holder to bind to the top-level interface of a chooser target service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bind to a condition provider service"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindMediaRouteService" msgid="6637740382272686835">"bind to a media route service"</string>
+    <string name="permdesc_bindMediaRouteService" msgid="6436655024972496687">"Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindDreamService" msgid="4153646965978563462">"bind to a dream service"</string>
+    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
+    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"access DRM certificates"</string>
+    <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Allows an application to provision and use DRM certficates. Should never be needed for normal apps."</string>
+    <string name="permlab_handoverStatus" msgid="1159132046126626731">"Receive Android Beam transfer status"</string>
+    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Allows this application to receive information about current Android Beam transfers"</string>
+    <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remove DRM certificates"</string>
+    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bind to a carrier messaging service"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitor the number of incorrect passwords typed when unlocking the screen and lock the tablet or erase all the tablet\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the TV or erase all the TV\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitor the number of incorrect passwords typed when unlocking the screen and lock the phone or erase all the phone\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the tablet or erase all this user\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the TV or erase all this user\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the phone or erase all this user\'s data if too many incorrect passwords are typed."</string>
+    <string name="policylab_resetPassword" msgid="4934707632423915395">"Change the screen lock"</string>
+    <string name="policydesc_resetPassword" msgid="1278323891710619128">"Change the screen lock."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Lock the screen"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Control how and when the screen locks."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Erase all data"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Erase the tablet\'s data without warning by performing a factory data reset."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Erase the TV\'s data without warning by performing a factory data reset."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Erase the phone\'s data without warning by performing a factory data reset."</string>
+    <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Erase user data"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Erase this user\'s data on this tablet without warning."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Erase this user\'s data on this TV without warning."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Erase this user\'s data on this phone without warning."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Set the device global proxy"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Set the device global proxy to be used while policy is enabled. Only the device owner can set the global proxy."</string>
+    <string name="policylab_expirePassword" msgid="5610055012328825874">"Set screen lock password expiry"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"Change how frequently the screen lock password, PIN or pattern must be changed."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Set storage encryption"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Require that stored app data be encrypted."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Disable cameras"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Prevent use of all device cameras."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="3565888260412415862">"Disable features of screen lock"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3980868516629887575">"Prevent use of some features of screen lock."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Home"</item>
+    <item msgid="869923650527136615">"Mobile"</item>
+    <item msgid="7897544654242874543">"Work"</item>
+    <item msgid="1103601433382158155">"Work Fax"</item>
+    <item msgid="1735177144948329370">"Home Fax"</item>
+    <item msgid="603878674477207394">"Pager"</item>
+    <item msgid="1650824275177931637">"Other"</item>
+    <item msgid="9192514806975898961">"Custom"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Home"</item>
+    <item msgid="7084237356602625604">"Work"</item>
+    <item msgid="1112044410659011023">"Other"</item>
+    <item msgid="2374913952870110618">"Custom"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Home"</item>
+    <item msgid="5629153956045109251">"Work"</item>
+    <item msgid="4966604264500343469">"Other"</item>
+    <item msgid="4932682847595299369">"Custom"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Home"</item>
+    <item msgid="1359644565647383708">"Work"</item>
+    <item msgid="7868549401053615677">"Other"</item>
+    <item msgid="3145118944639869809">"Custom"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Work"</item>
+    <item msgid="4378074129049520373">"Other"</item>
+    <item msgid="3455047468583965104">"Custom"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Custom"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Home"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobile"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Work"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Work Fax"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Home Fax"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Other"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Callback"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Car"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Company Main"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Main"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Other Fax"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Work Mobile"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Work Pager"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Customised"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Birthday"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversary"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Other"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Custom"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Home"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Work"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Other"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobile"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Custom"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Home"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Work"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Other"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Custom"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Home"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Work"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Other"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Custom"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
+    <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+    <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+    <string name="imProtocolNetMeeting" msgid="8287625655986827971">"Net Meeting"</string>
+    <string name="orgTypeWork" msgid="29268870505363872">"Work"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Other"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Custom"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Customised"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistant"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Brother"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Child"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Domestic Partner"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Father"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Friend"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Manager"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Mother"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Parent"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Referred by"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Relative"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Sister"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Spouse"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Customised"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN Code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu, then 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Emergency number"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"No service"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Screen locked."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Press Menu to unlock or place emergency call."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Press Menu to unlock."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Draw pattern to unlock"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Emergency call"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Return to call"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correct!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No SIM card in phone."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insert a SIM card."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"The SIM card is missing or not readable. Insert a SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Unusable SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+    <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Previous track"</string>
+    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Next track"</string>
+    <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pause"</string>
+    <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Play"</string>
+    <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Stop"</string>
+    <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Rewind"</string>
+    <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Fast-forward"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Emergency calls only"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Network locked"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM card is PUK-locked."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Forgotten pattern?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account unlock"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Too many pattern attempts"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"To unlock, sign in with your Google account."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Username (email)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Sign in"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Invalid username or password."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Forgot your username or password?\nVisit "<b>"google.co.uk/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Checking…"</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sound off"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Pattern started"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Pattern cleared"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+    <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>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"character"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
+    <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">"Factory test failed"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Reboot"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"The page at \"<xliff:g id="TITLE">%s</xliff:g>\" says:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirm Navigation"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Leave this Page"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Stay on this Page"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAre you sure you want to navigate away from this page?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Confirm"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Tip: double-tap to zoom in and out."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Auto-fill"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Set up Auto-fill"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Province"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Postcode"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"State"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Zip code"</string>
+    <string name="autofill_county" msgid="237073771020362891">"County"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Island"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"District"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Department"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefecture"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Parish"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Area"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"read your Web bookmarks and history"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Allows the app to read the history of all URLs that the Browser has visited, and all of the Browser\'s bookmarks. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"write web bookmarks and history"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Allows the app to modify the Browser\'s history or bookmarks stored on your tablet. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Allows the app to modify the Browser\'s history or bookmarks stored on your TV. This may allow the app to erase or modify Browser data. Note: This permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Allows the app to modify the Browser\'s history or bookmarks stored on your phone. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"set an alarm"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Allows the app to set an alarm in an installed alarm clock app. Some alarm clock apps may not implement this feature."</string>
+    <string name="permlab_writeVoicemail" msgid="7309899891683938100">"write voicemails"</string>
+    <string name="permdesc_writeVoicemail" msgid="6592572839715924830">"Allows the app to modify and remove messages from your voicemail inbox."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"add voicemail"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Allows the app to add messages to your voicemail inbox."</string>
+    <string name="permlab_readVoicemail" msgid="8415201752589140137">"read voicemail"</string>
+    <string name="permdesc_readVoicemail" msgid="8926534735321616550">"Allows the app to read your voicemails."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modify Browser geo-location permissions"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Allows the app to modify the Browser\'s geo-location permissions. Malicious apps may use this to allow sending location information to arbitrary websites."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verify packages"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Allows the app to verify a package is installable."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"bind to a package verifier"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Allows the holder to make requests of package verifiers. Should never be needed for normal apps."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"access serial ports"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Allows the holder to access serial ports using the SerialManager API."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"access content providers externally"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Allows the holder to access content providers from the shell. Should never be needed for normal apps."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"discourage automatic device updates"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Allows the holder to offer information to the system about when would be a good time for a non-interactive reboot to upgrade the device."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Do you want the browser to remember this password?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Not now"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Remember"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Never"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"You don\'t have permission to open this page."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Text copied to clipboard."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"More"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
+    <string name="search_go" msgid="8298016669822141719">"Search"</string>
+    <string name="search_hint" msgid="1733947260773056054">"Search…"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Search"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Search query"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Clear query"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Submit query"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Voice search"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Enable Explore by Touch?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 month ago"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Before 1 month ago"</string>
+    <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
+      <item quantity="other">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+      <item quantity="one">Last <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+    </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Last month"</string>
+    <string name="older" msgid="5211975022815554840">"Older"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"on <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"at <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"in<xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"day"</string>
+    <string name="days" msgid="4774547661021344602">"days"</string>
+    <string name="hour" msgid="2126771916426189481">"hour"</string>
+    <string name="hours" msgid="894424005266852993">"hours"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"mins"</string>
+    <string name="second" msgid="3184235808021478">"sec"</string>
+    <string name="seconds" msgid="3161515347216589235">"secs"</string>
+    <string name="week" msgid="5617961537173061583">"week"</string>
+    <string name="weeks" msgid="6509623834583944518">"weeks"</string>
+    <string name="year" msgid="4001118221013892076">"year"</string>
+    <string name="years" msgid="6881577717993213522">"years"</string>
+    <plurals name="duration_seconds" formatted="false" msgid="4527986939729687805">
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> seconds</item>
+      <item quantity="one">1 second</item>
+    </plurals>
+    <plurals name="duration_minutes" formatted="false" msgid="643786953939956125">
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> minutes</item>
+      <item quantity="one">1 minute</item>
+    </plurals>
+    <plurals name="duration_hours" formatted="false" msgid="6826233369186668274">
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> hours</item>
+      <item quantity="one">1 hour</item>
+    </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"noon"</string>
+    <string name="Noon" msgid="3342127745230013127">"Noon"</string>
+    <string name="midnight" msgid="7166259508850457595">"midnight"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Midnight"</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">"Select all"</string>
+    <string name="cut" msgid="3092569408438626261">"Cut"</string>
+    <string name="copy" msgid="2681946229533511987">"Copy"</string>
+    <string name="paste" msgid="5629880836805036433">"Paste"</string>
+    <string name="replace" msgid="5781686059063148930">"Replace..."</string>
+    <string name="delete" msgid="6098684844021697789">"Delete"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Copy URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Select text"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Text selection"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Add to dictionary"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Delete"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Touch for more information or to stop the app."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Cancel"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Attention"</string>
+    <string name="loading" msgid="7933681260296021180">"Loading…"</string>
+    <string name="capital_on" msgid="1544682755514494298">"ON"</string>
+    <string name="capital_off" msgid="6815870386972805832">"OFF"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Complete action using"</string>
+    <string name="whichApplicationNamed" msgid="8260158865936942783">"Complete action using %1$s"</string>
+    <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
+    <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
+    <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
+    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
+    <string name="whichSendApplication" msgid="6902512414057341668">"Share with"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Share with %1$s"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"Select a Home app"</string>
+    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Use %1$s as Home"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Use by default for this action."</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"Use a different app"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Clear default in System settings &gt; Apps &gt; Downloaded."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Choose an action"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Choose an app for the USB device"</string>
+    <string name="noApplications" msgid="2991814273936504689">"No apps can perform this action."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> isn\'t responding. Do you want to close it?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Report"</string>
+    <string name="wait" msgid="7147118217226317732">"Wait"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive.\n\nDo you want to close it?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"App redirected"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is now running."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was originally launched."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scale"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Always show"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Re-enable this in System settings &gt; Apps &gt; Downloaded."</string>
+    <string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced Strict Mode policy."</string>
+    <string name="smv_process" msgid="5120397012047462446">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has violated its self-enforced StrictMode policy."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android is upgrading…"</string>
+    <string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
+    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_preparing_apk" msgid="8162599310274079154">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Touch to switch to app"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+    <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Heap dump has been collected; touch to share"</string>
+    <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+    <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Playing through Bluetooth"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Silent ringtone set"</string>
+    <string name="volume_call" msgid="3941680041282788711">"In-call volume"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth in-call volume"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Alarm volume"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Notification volume"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Volume"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth volume"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Ringtone volume"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Call volume"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="other">Wi-Fi networks available</item>
+      <item quantity="one">Wi-Fi network available</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="other">Open Wi-Fi networks available</item>
+      <item quantity="one">Open Wi-Fi network available</item>
+    </plurals>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+    <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Allow connection?"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Application %1$s would like to connect to Wi-Fi Network %2$s"</string>
+    <string name="wifi_connect_default_application" msgid="7143109390475484319">"An application"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct is on"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Touch for settings"</string>
+    <string name="accept" msgid="1645267259272829559">"Accept"</string>
+    <string name="decline" msgid="2112225451706137894">"Decline"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation sent"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitation to connect"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"From:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"To:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Type the required PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"The TV will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"Insert character"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"Sending SMS messages"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; is sending a large number of SMS messages. Do you want to allow this app to continue sending messages?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Allow"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Deny"</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; would like to send a message to &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="5873295990846059400">"This "<b>"may cause charges"</b>" on your mobile account."</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"This will cause charges on your mobile account."</b></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Send"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Cancel"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Remember my choice"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"You can change this later in Settings &gt; Apps"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Always Allow*"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Never Allow"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM card removed"</string>
+    <string name="sim_removed_message" msgid="5450336489923274918">"The mobile network will be unavailable until you restart with a valid SIM card inserted."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Done"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM card added"</string>
+    <string name="sim_added_message" msgid="7797975656153714319">"Restart your device to access the mobile network."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Restart"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Set time"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Done"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NEW: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Provided by <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"this may cost you money"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB mass storage"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB connected"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s USB storage."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s SD card."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Turn on USB storage"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"There\'s a problem using your USB storage for USB mass storage."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"There\'s a problem using your SD card for USB mass storage."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB connected"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Touch to copy files to/from your computer."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Turn off USB storage"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Touch to turn off USB storage."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB storage in use"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Before turning off USB storage, unmount (\"eject\") your Android\'s USB storage from your computer."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Before turning off USB storage, unmount (\"eject\") your Android\'s SD card from your computer."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Turn off USB storage"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"There was a problem turning off USB storage. Check that you\'ve unmounted the USB host, then try again."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Turn off USB storage"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"If you turn on USB storage, some apps that you\'re using will stop and may be unavailable until you turn off USB storage."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB operation unsuccessful"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
+    <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connected as a MIDI device"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Touch for other USB options."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format USB storage?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format SD card?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"All files stored in your USB storage will be erased. This action can\'t be reversed!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"All data on your card will be lost."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
+    <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
+    <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
+    <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</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>"candidates"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Preparing USB storage"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Preparing SD card"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Checking for errors."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Blank USB storage"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Blank SD card"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB storage is blank or has unsupported filesystem."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD card is blank or has unsupported file system."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Damaged USB storage"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Damaged SD card"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB storage is damaged. Try reformatting it."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD card is damaged. Try reformatting it."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB storage removed unexpectedly"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD card removed unexpectedly"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Unmount USB storage before removing to avoid data loss."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Unmount SD card before removing to avoid data loss."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB storage safe to remove"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD card safe to remove"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"You can safely remove USB storage."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"You can safely remove SD card."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Removed USB storage"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Removed SD card"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB storage removed. Insert new media."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD card removed. Insert a new one."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"update component usage statistics"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Allows the app to modify collected component usage statistics. Not for use by normal apps."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"copy content"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Allows the app to invoke default container service to copy content. Not for use by normal apps."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Access keyguard secure storage"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Allows an application to access keyguard secure storage."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Control displaying and hiding keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Allows an application to control keyguard."</string>
+    <string name="permlab_trust_listener" msgid="1765718054003704476">"Listen to trust state changes."</string>
+    <string name="permdesc_trust_listener" msgid="8233895334214716864">"Allows an application to listen for changes in trust state."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Provide a trust agent."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Allows an application to provide a trust agent."</string>
+    <string name="permlab_launch_trust_agent_settings" msgid="5859430082240410200">"Launch trust agent settings menu."</string>
+    <string name="permdesc_launch_trust_agent_settings" msgid="8185142708644913381">"Allows an application to launch an activity that changes the trust agent behaviour."</string>
+    <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Bind to a trust agent service"</string>
+    <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Allows an application to bind to a trust agent service."</string>
+    <string name="permlab_recovery" msgid="3157024487744125846">"Interact with update and recovery system"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Allows an application to interact with the recovery system and system updates."</string>
+    <string name="permlab_manageMediaProjection" msgid="1120495449419929218">"Manage media projection sessions"</string>
+    <string name="permdesc_manageMediaProjection" msgid="8053759147529492856">"Allows an application to manage media projection sessions. These sessions can provide applications with the ability to capture display and audio contents. Should never be needed by normal apps."</string>
+    <string name="permlab_readInstallSessions" msgid="6165432407628065939">"Read install sessions"</string>
+    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Allows an application to read install sessions. This allows it to see details about active package installations."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Touch twice for zoom control"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Go"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Search"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Send"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Next"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Done"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Prev"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Execute"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dial number\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Create contact\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"The following one or more applications request permission to access your account, now and in the future."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Do you want to allow this request?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Access request"</string>
+    <string name="allow" msgid="7225948811296386551">"Allow"</string>
+    <string name="deny" msgid="2081879885755434506">"Deny"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Permission requested"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permission requested\nfor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="forward_intent_to_owner" msgid="1207197447013960896">"You\'re using this app outside of your work profile"</string>
+    <string name="forward_intent_to_work" msgid="621480743856004612">"You\'re using this app in your work profile"</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Input Method"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sync"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibility"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string>
+    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Condition provider"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Touch to manage the network."</string>
+    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN connecting…"</string>
+    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN connected"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"Always-on VPN error"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Touch to configure"</string>
+    <string name="upload_file" msgid="2897957172366730416">"Choose file"</string>
+    <string name="no_file_chosen" msgid="6363648562170759465">"No file chosen"</string>
+    <string name="reset" msgid="2448168080964209908">"Reset"</string>
+    <string name="submit" msgid="1602335572089911941">"Submit"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Car mode enabled"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Touch to exit car mode."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Touch to set up."</string>
+    <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
+    <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
+    <string name="no_matches" msgid="8129421908915840737">"No matches"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Find on page"</string>
+    <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
+      <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
+      <item quantity="one">1 match</item>
+    </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Done"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Unmounting USB storage…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Unmounting SD card…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Erasing USB storage..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Erasing SD card…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Couldn\'t erase USB storage."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"Couldn\'t erase SD card."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD card was removed before being unmounted."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB storage is currently being checked."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD card is currently being checked."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD card has been removed."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB storage is currently in use by a computer."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD card is currently in use by a computer."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"External media in unknown state."</string>
+    <string name="share" msgid="1778686618230011964">"Share"</string>
+    <string name="find" msgid="4808270900322985960">"Find"</string>
+    <string name="websearch" msgid="4337157977400211589">"Web Search"</string>
+    <string name="find_next" msgid="5742124618942193978">"Find next"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Find previous"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Location request from <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Location request"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Requested by <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Deletion limit exceeded"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"There are <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> deleted items for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. What do you want to do?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Delete the items"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Undo the deletes"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Do nothing for now"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Choose an account"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Add an account"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Increase"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Decrease"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Slide up to increase and down to decrease."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Increase minute"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Decrease minute"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Increase hour"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Decrease hour"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Set p.m."</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Set a.m."</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Increase month"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Decrease month"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Increase day"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Decrease day"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Increase year"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Decrease year"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</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">"Choose an app"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Couldn\'t launch <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch &amp; hold."</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plug in a headset to hear password keys spoken."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</string>
+    <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
+    <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
+    <string name="storage_internal" msgid="4891916833657929263">"Internal storage"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Data usage warning"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Touch to view usage and settings."</string>
+    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G data limit reached"</string>
+    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G data limit reached"</string>
+    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Mobile data limit reached"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi data limit reached"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Data paused for rest of cycle"</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G data limit exceeded"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G data limit exceeded"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Mobile data limit exceeded"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi data limit exceeded"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> over specified limit."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Background data restricted"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Touch to remove restriction."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Security certificate"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"This certificate is valid."</string>
+    <string name="issued_to" msgid="454239480274921032">"Issued to:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Common name:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organisation:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Organisational unit:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Issued by:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Validity:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Issued on:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Expires on:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Serial number:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Fingerprints:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 fingerprint"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 fingerprint"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"See all"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Choose activity"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Share with"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Sending…"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
+    <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
+    <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Phone"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Headphones"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock speakers"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Wireless display"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Cast"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Connect to device"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Cast screen to device"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Searching for devices…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Settings"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Disconnect"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Scanning..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Connecting..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Not available"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In use"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Built-in Screen"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Screen"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<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>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%1$d</xliff:g> seconds."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="owner_name" msgid="2716755460376028154">"Owner"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"This change isn\'t allowed by your administrator"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
+    <string name="revoke" msgid="5404479185228271586">"Revoke"</string>
+    <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
+    <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
+    <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string>
+    <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3"</string>
+    <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4"</string>
+    <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5"</string>
+    <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6"</string>
+    <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7"</string>
+    <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8"</string>
+    <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9"</string>
+    <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10"</string>
+    <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0"</string>
+    <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1"</string>
+    <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2"</string>
+    <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3"</string>
+    <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4"</string>
+    <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5"</string>
+    <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6"</string>
+    <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7"</string>
+    <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8"</string>
+    <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9"</string>
+    <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10"</string>
+    <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0"</string>
+    <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1"</string>
+    <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2"</string>
+    <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3"</string>
+    <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4"</string>
+    <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5"</string>
+    <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6"</string>
+    <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7"</string>
+    <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8"</string>
+    <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9"</string>
+    <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10"</string>
+    <string name="mediasize_na_letter" msgid="2841414839888344296">"Letter"</string>
+    <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter"</string>
+    <string name="mediasize_na_legal" msgid="8621364037680465666">"Legal"</string>
+    <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string>
+    <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string>
+    <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid"</string>
+    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3 x 5"</string>
+    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4 x 6"</string>
+    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5 x 8"</string>
+    <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string>
+    <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string>
+    <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string>
+    <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K"</string>
+    <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K"</string>
+    <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1"</string>
+    <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2"</string>
+    <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3"</string>
+    <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4"</string>
+    <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5"</string>
+    <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6"</string>
+    <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7"</string>
+    <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8"</string>
+    <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9"</string>
+    <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10"</string>
+    <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K"</string>
+    <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai"</string>
+    <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai"</string>
+    <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai"</string>
+    <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10"</string>
+    <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9"</string>
+    <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8"</string>
+    <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7"</string>
+    <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6"</string>
+    <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5"</string>
+    <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4"</string>
+    <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3"</string>
+    <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2"</string>
+    <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1"</string>
+    <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0"</string>
+    <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec"</string>
+    <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4"</string>
+    <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3"</string>
+    <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2"</string>
+    <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki"</string>
+    <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku"</string>
+    <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
+    <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
+    <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Unknown portrait"</string>
+    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Unknown landscape"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
+    <string name="reason_service_unavailable" msgid="7824008732243903268">"Print service not enabled"</string>
+    <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> service installed"</string>
+    <string name="print_service_installed_message" msgid="5897362931070459152">"Tap to enable"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Enter administrator PIN"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirm new PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Create a PIN for modifying restrictions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINs don\'t match. Try again."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN is too short. Must be at least 4 digits."</string>
+    <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
+      <item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
+      <item quantity="one">Try again in 1 second</item>
+    </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Viewing full screen"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"To exit, swipe down from the top."</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Got it"</string>
+    <string name="done_label" msgid="2093726099505892398">"Done"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
+    <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+    <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
+    <string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="lock_to_app_toast" msgid="7570091317001980053">"To unpin this screen, touch and hold Back and Overview at the same time."</string>
+    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"To unpin this screen, touch and hold Overview."</string>
+    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
+    <string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
+    <string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
+    <string name="downtime_condition_summary" msgid="8761776337475705749">"Until your downtime ends at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="downtime_condition_line_one" msgid="8762708714645352010">"Until your downtime ends"</string>
+    <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
+      <item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
+      <item quantity="other">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For one hour (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
+      <item quantity="other">For %d minutes</item>
+      <item quantity="one">For one minute</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
+      <item quantity="other">For %d hours</item>
+      <item quantity="one">For one hour</item>
+    </plurals>
+    <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
+    <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
+    <string name="zen_mode_next_alarm_summary" msgid="5915140424683747372">"Until next alarm at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_next_alarm_line_one" msgid="5537042951553420916">"Until next alarm"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
+    <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD request is modified to DIAL request."</string>
+    <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD request is modified to SS request."</string>
+    <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD request is modified to new USSD request."</string>
+    <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
+    <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
+    <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
+    <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
+    <string name="usb_midi_peripheral_model_name" msgid="1959288763942653301">"USB Peripheral Port"</string>
+</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index eafd4dc..f52daf6 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assist"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index eafd4dc..f52daf6 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assist"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 23446ff..ce419dc 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"El modo avión está Activado"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"El modo avión está Desactivado"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Configuración"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asistencia"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0e42076..e22ea21 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Banner de itinerancia activado"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Banner de itinerancia desactivado"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamadas Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: No desviada"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avión activado. Desactivar"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avión desactivado. Activar"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Ajustes"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asistencia"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt; 999"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Red Wi-Fi abierta disponible</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sesión en red Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No se ha podido establecer conexión con la red Wi-Fi."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index c7e78ea..85b5c3c 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lennurežiim on SEES"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lennurežiim on VÄLJAS"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Seaded"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Abi"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index a97245e..02d8dd3 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Ibiltaritzari buruzko jakinarazpena aktibatuta"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Ibiltaritzari buruzko jakinarazpena desaktibatuta"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Zerbitzu bila"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi bidezko deiak"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ez da desbideratu"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hegaldi modua AKTIBATUTA dago"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hegaldi modua DESAKTIBATUTA dago"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Ezarpenak"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Lagundu"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ahots-laguntza"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">Wi-Fi sare irekiak erabilgarri</item>
       <item quantity="one">Wi-Fi sare irekia erabilgarri</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Hasi saioa Wi-Fi sarean"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ezin izan da Wi-Fi sarera konektatu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 58a53b5..2073b5e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"دستیار"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 37718fa..a2f1ccf 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lentokonetila on KÄYTÖSSÄ"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lentokonetila on POIS KÄYTÖSTÄ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Asetukset"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Auta"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ääniapuri"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 98a299f..837b58a 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Paramètres"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistance"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7a4a5da..c6e1387 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Bannière d\'itinérance activée"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Bannière d\'itinérance désactivée"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Paramètres"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistance"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assistance vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="other">Réseaux Wi-Fi ouverts disponibles</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossible de se connecter au Wi-Fi."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 97b2390..5218ed5 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Banner de itinerancia activado"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Banner de itinerancia desactivado"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servizo"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por wifi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: non desviada"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"O modo avión está activado"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"O modo avión está desactivado"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Configuración"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asistencia"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">Abrir redes wifi dispoñibles</item>
       <item quantity="one">Abrir rede wifi dispoñible</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia sesión na rede wifi"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Non se puido conectar coa rede Wi-Fi"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 1738852..6463cc5 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"रोमिंग बैनर चालू"</string>
     <string name="roamingText12" msgid="1189071119992726320">"रोमिंग बैनर बंद"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"सहायता"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"वॉइस सहायक"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="other">खुले वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई  नेटवर्क में प्रवेश करें"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में प्रवेश करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाई-फ़ाई  से कनेक्‍ट नहीं हो सका"</string>
@@ -1526,7 +1525,7 @@
     <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="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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a497fd7..0f39d7c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -124,8 +124,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Uključen je natpis roaminga"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Isključen je natpis roaminga"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđeno"</string>
@@ -205,6 +204,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uključen je način rada u zrakoplovu"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Isključen je način rada u zrakoplovu"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Postavke"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pomoć"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj sada"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1309,8 +1309,7 @@
       <item quantity="other">Dostupne su otvorene Wi-Fi mreže</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijava na Wi-Fi mrežu"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ne može se spojiti na Wi-Fi"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 2908103..adada44 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Barangolást jelző szalaghirdetés bekapcsolva"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Barangolást jelző szalaghirdetés kikapcsolva"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Szolgáltatás keresése"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-hívás"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nincs átirányítva"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Repülőgép üzemmód bekapcsolva"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Repülőgép üzemmód kikapcsolva"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Beállítások"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Segítség"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hangsegéd"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Nyílt Wi-Fi hálózat érhető el</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Bejelentkezés Wi-Fi hálózatba"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nem sikerült csatlakozni a Wi-Fi hálózathoz"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 86b5665..65bacf7 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Ռոումինգի ազդերիզը միացված է"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Ռոումինգի ազդերիզն անջատված է"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Զանգեր Wi-Fi-ի միջոցով"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. Չի վերահասցեավորվել"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Օգնական"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Կողպել հիմա"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="other">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Մուտք գործեք Wi-Fi ցանց"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Չհաջողվեց միանալ Wi-Fi-ին"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ddeefa8..2f7cb25 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode pesawat AKTIF"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode pesawat MATI"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Setelan"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Bantuan"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Bantuan"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 957a224..a926d3d 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"KVEIKT er á flugstillingu"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"SLÖKKT er á flugstillingu"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Stillingar"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Aðstoð"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Raddaðstoð"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Læsa núna"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e04c8e4..74ad5f7 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modalità aereo attiva"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modalità aereo non attiva"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Impostazioni"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistenza"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blocca ora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 25a6ffd..1e8d680 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -205,6 +205,7 @@
     <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_assist" msgid="3892832961594295030">"סיוע"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f13cba2..5598018 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"ローミングバナーON"</string>
     <string name="roamingText12" msgid="1189071119992726320">"ローミングバナーOFF"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"サービスを検索中"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi通話"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:転送できません"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"機内モードON"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"機内モードOFF"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"サポート"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"音声アシスト"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"今すぐロック"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Wi-Fiオープンネットワークが利用できます</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fiネットワークにログイン"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiに接続できませんでした"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index ee48141..d179c28 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner ჩართულია"</string>
     <string name="roamingText12" msgid="1189071119992726320">"როუმინგის ბანერი გამორთულია"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: არ არის გადამისამართებული"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"დახმარება"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ახლა ჩაკეტვა"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">ხელმისაწვდომია ღია Wi-Fi ქსელი</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ქსელთან დაკავშირება"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-თან დაკავშირება ვერ მოხერხდა"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 5c33647..caa12d2 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Роуминг баннері қосулы"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Роуминг баннері өшірулі"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Қызметті іздеу"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi қоңыраулары"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Басқа нөмірге бағытталмады"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Көмек"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Қазір бекіту"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">Ашық Wi-Fi желілері қол жетімді</item>
       <item quantity="one">Ашық Wi-Fi желісі қол жетімді</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi желісіне кіру"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi желісіне қосыла алмады"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index d028de8..3326462 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"បើក​បដា​រ៉ូមីង"</string>
     <string name="roamingText12" msgid="1189071119992726320">"បិទ​បដា​រ៉ូមីង"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ការហៅតាម Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិន​បាន​បញ្ជូន​បន្ត"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"ជំនួយ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ជំនួយសម្លេង"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោ​ឥឡូវនេះ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1304,8 +1304,7 @@
       <item quantity="one">បើកបណ្តាញ Wi-Fi ដែលមាន</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"មិន​​អាច​តភ្ជាប់​វ៉ាយហ្វាយ"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 307dcd1..2bd45d4 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"ರೋಮಿಂಗ್ ಬ್ಯಾನರ್ ಆನ್ ಆಗಿದೆ"</string>
     <string name="roamingText12" msgid="1189071119992726320">"ರೋಮಿಂಗ್ ಬ್ಯಾನರ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"ಸಹಾಯ ಮಾಡು"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ಈಗ ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
       <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 34807fd..463f84d5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"로밍 배너 사용"</string>
     <string name="roamingText12" msgid="1189071119992726320">"로밍 배너 사용 안함"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"서비스 검색 중"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 통화"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: 착신전환 안됨"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"지원"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"지금 잠그기"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">개방형 Wi-Fi 네트워크 사용 가능</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi 네트워크에 로그인"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi에 연결할 수 없습니다"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 97c2497..fdfc442 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -191,8 +191,7 @@
     <skip />
     <!-- no translation found for roamingTextSearching (8360141885972279963) -->
     <skip />
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <!-- no translation found for cfTemplateNotForwarded (1683685883841272560) -->
@@ -309,6 +308,7 @@
     <!-- no translation found for global_actions_airplane_mode_off_status (5075070442854490296) -->
     <skip />
     <string name="global_action_settings" msgid="1756531602592545966">"Жөндөөлөр"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Жардам"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string>
     <!-- no translation found for status_bar_notification_info_overflow (5301981741705354993) -->
@@ -1705,10 +1705,8 @@
       <item quantity="other">Ачык Wi-Fi тармагы жеткиликтүү</item>
       <item quantity="one">Ачык Wi-Fi тармагы жеткиликтүү</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi түйүнүнө кирүү"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi менен туташуу түзүлбөдү"</string>
diff --git a/core/res/res/values-land/dimens_material.xml b/core/res/res/values-land/dimens_material.xml
index 379ccf6..202f4a4 100644
--- a/core/res/res/values-land/dimens_material.xml
+++ b/core/res/res/values-land/dimens_material.xml
@@ -48,4 +48,14 @@
     <dimen name="timepicker_text_inset_inner">46dp</dimen>
     <dimen name="timepicker_text_size_normal">14sp</dimen>
     <dimen name="timepicker_text_size_inner">12sp</dimen>
+
+    <!-- Used by Material-style SimpleMonthView -->
+    <dimen name="date_picker_month_height">40dp</dimen>
+    <dimen name="date_picker_day_of_week_height">14dp</dimen>
+    <dimen name="date_picker_day_height">32dp</dimen>
+    <dimen name="date_picker_day_width">46dp</dimen>
+    <dimen name="date_picker_day_selector_radius">16dp</dimen>
+    <dimen name="day_picker_padding_horizontal">18dp</dimen>
+    <dimen name="day_picker_padding_top">0dp</dimen>
+    <dimen name="day_picker_button_margin_top">-8dp</dimen>
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index be720e8..e565c00 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"ຕົວຊ່ວຍ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ຊ່ວຍ​ເຫຼືອ​ທາງ​ສຽງ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກ​ດຽວ​ນີ້"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5f42e39..099593c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -125,8 +125,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Tarptinklinio ryšio reklamjuostė įjungta"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Tarptinklinio ryšio reklamjuostė išjungta"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Ieškoma paslaugos"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"„Wi-Fi“ skambinimas"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neperadresuota"</string>
@@ -206,6 +205,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"ĮJUNGTAS lėktuvo režimas"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"lėktuvo režimas IŠJUNGTAS"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Nustatymai"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pagalba"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Užrakinti dabar"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1316,8 +1316,7 @@
       <item quantity="other">Pasiekiami atvirieji „Wi-Fi“ tinklai</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prisijungti prie „Wi-Fi“ tinklo"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepavyko prisijungti prie „Wi-Fi“"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 75b4fe1..9ab2772 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -124,8 +124,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Viesabonēšanas reklāmkarogs ir ieslēgts."</string>
     <string name="roamingText12" msgid="1189071119992726320">"Viesabonēšanas reklāmkarogs ir izslēgts."</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Pakalpojuma meklēšana"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zvani"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nav pāradresēts"</string>
@@ -205,6 +204,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lidojuma režīms ir IESLĒGTS."</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lidojuma režīms ir IZSLĒGTS."</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Iestatījumi"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Palīdzība"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloķēt tūlīt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
@@ -1309,8 +1309,7 @@
       <item quantity="other">Ir pieejami atvērti Wi-Fi tīkli</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Pierakstieties Wi-Fi tīklā"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nevarēja izveidot savienojumu ar Wi-Fi."</string>
diff --git a/core/res/res/values-mcc310-mnc260-bg/strings.xml b/core/res/res/values-mcc310-mnc260-bg/strings.xml
new file mode 100644
index 0000000..86ad9ab
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-bg/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Обажданията през Wi-Fi не са налице. Свържете се с оператора си, за да ги активирате."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bn-rBD/strings.xml b/core/res/res/values-mcc310-mnc260-bn-rBD/strings.xml
new file mode 100644
index 0000000..97df2db
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-bn-rBD/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi কলিং উপলব্ধ নেই৷ Wi-Fi কলিং সক্ষম করতে আপনার পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন৷"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ca/strings.xml b/core/res/res/values-mcc310-mnc260-ca/strings.xml
new file mode 100644
index 0000000..e7d2158
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ca/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Les trucades per Wi-Fi no estan disponibles. Contacta amb l\'operador de telefonia mòbil per activar-les."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-cs/strings.xml b/core/res/res/values-mcc310-mnc260-cs/strings.xml
new file mode 100644
index 0000000..987284d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-cs/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Volání přes Wi-Fi není k dispozici. Kontaktujte operátora, aby volání přes Wi-Fi aktivoval."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-de/strings.xml b/core/res/res/values-mcc310-mnc260-de/strings.xml
new file mode 100644
index 0000000..e69d062
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-de/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"WLAN-Anrufe sind nicht möglich. Bitte kontaktieren Sie Ihren Mobilfunkanbieter bezüglich der Aktivierung der WLAN-Telefonie."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
new file mode 100644
index 0000000..3f764c0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi Calling isn\'t available. Contact your operator to enable Wi-Fi Calling."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es/strings.xml b/core/res/res/values-mcc310-mnc260-es/strings.xml
new file mode 100644
index 0000000..9dea2f1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-es/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Las llamadas Wi-Fi no están disponibles. Ponte en contacto con tu operador para habilitarlas."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-eu-rES/strings.xml b/core/res/res/values-mcc310-mnc260-eu-rES/strings.xml
new file mode 100644
index 0000000..23194ff
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-eu-rES/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi bidezko deiak ez daude erabilgarri. Gaitzeko, jarri operadorearekin harremanetan."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr/strings.xml b/core/res/res/values-mcc310-mnc260-fr/strings.xml
new file mode 100644
index 0000000..358bec8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-fr/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Les appels Wi-Fi ne sont pas disponibles. Contactez votre opérateur pour les activer."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gl-rES/strings.xml b/core/res/res/values-mcc310-mnc260-gl-rES/strings.xml
new file mode 100644
index 0000000..32ef3d3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-gl-rES/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"As chamadas por wifi non están dispoñible. Contacta co teu operador para activar as chamadas por wifi."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hi/strings.xml b/core/res/res/values-mcc310-mnc260-hi/strings.xml
new file mode 100644
index 0000000..93193fd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-hi/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi कॉलिंग उपलब्‍ध नहीं है. वाई-फ़ाई कॉलिंग सक्षम करने के लिए अपने वाहक से संपर्क करें."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hr/strings.xml b/core/res/res/values-mcc310-mnc260-hr/strings.xml
new file mode 100644
index 0000000..30e22f1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-hr/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi pozivi nisu dostupni. Obratite se mobilnom operateru radi omogućivanja Wi-Fi poziva."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hu/strings.xml b/core/res/res/values-mcc310-mnc260-hu/strings.xml
new file mode 100644
index 0000000..44b0a9e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-hu/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"A Wi-Fi-hívás nem érhető el. Engedélyezéséhez forduljon szolgáltatójához."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hy-rAM/strings.xml b/core/res/res/values-mcc310-mnc260-hy-rAM/strings.xml
new file mode 100644
index 0000000..aa63f70
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-hy-rAM/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi-ի միջոցով զանգերն անհասանելի են: Դրանք միացնելու համար դիմեք ձեր օպերատորին:"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ja/strings.xml b/core/res/res/values-mcc310-mnc260-ja/strings.xml
new file mode 100644
index 0000000..237b606
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ja/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi通話が利用できません。携帯通信会社に連絡してWi-Fi通話を有効にしてください。"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ka-rGE/strings.xml b/core/res/res/values-mcc310-mnc260-ka-rGE/strings.xml
new file mode 100644
index 0000000..53488dd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ka-rGE/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"დარეკვა Wi-Fi-ს მეშვეობით მიუწვდომელია. დაუკავშირდით თქვენს ოპერატორს Wi-Fi-ს მეშვეობით დარეკვის ჩასართავად."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kk-rKZ/strings.xml b/core/res/res/values-mcc310-mnc260-kk-rKZ/strings.xml
new file mode 100644
index 0000000..10ce253
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-kk-rKZ/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi қоңырауы қол жетімді емес. Wi-Fi қоңырауы қосу үшін жабдықтаушыға хабарласыңыз."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-km-rKH/strings.xml b/core/res/res/values-mcc310-mnc260-km-rKH/strings.xml
new file mode 100644
index 0000000..7f62ff6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-km-rKH/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"ការហៅតាម Wi-Fi មិនមាននោះទេ។ សូមទាក់ទងទៅអ្នកផ្តល់សេវាកម្មទូរស័ព្ទរបស់អ្នកដើម្បីបើកដំណើរការហៅតាម Wi-Fi។"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kn-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-kn-rIN/strings.xml
new file mode 100644
index 0000000..4977708
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-kn-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ ಲಭ್ಯವಿಲ್ಲ. ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ko/strings.xml b/core/res/res/values-mcc310-mnc260-ko/strings.xml
new file mode 100644
index 0000000..0dcc45a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ko/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi 통화를 사용할 수 없습니다. Wi-Fi 통화를 사용하려면 이동통신사에 문의하세요."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc260-ky-rKG/strings.xml
new file mode 100644
index 0000000..b8f1e5a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ky-rKG/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi Чалуу жеткиликтүү эмес. Wi-Fi Чалууну иштетүү үчүн операторуңузга кайрылыңыз."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lt/strings.xml b/core/res/res/values-mcc310-mnc260-lt/strings.xml
new file mode 100644
index 0000000..b4a0dbb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-lt/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"„Wi-Fi“ skambinimo funkcija nepasiekiama. Susisiekite su operatoriumi, kad įgalintumėte „Wi-Fi“ skambinimo funkciją."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lv/strings.xml b/core/res/res/values-mcc310-mnc260-lv/strings.xml
new file mode 100644
index 0000000..19fafeb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-lv/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi zvani nav pieejami. Lai iespējotu Wi-Fi zvanus, sazinieties ar savu mobilo sakaru operatoru."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mk-rMK/strings.xml b/core/res/res/values-mcc310-mnc260-mk-rMK/strings.xml
new file mode 100644
index 0000000..a4125b4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-mk-rMK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Повикувањето преку Wi-Fi не е достапно. Контактирајте го операторот за да овозможите Повикување преку Wi-Fi."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ml-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-ml-rIN/strings.xml
new file mode 100644
index 0000000..732e18b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ml-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi കോളിംഗ് ലഭ്യമല്ല. Wi-Fi കോളിംഗ് പ്രവർത്തനക്ഷമമാക്കാൻ നിങ്ങളുടെ കാരിയറെ ബന്ധപ്പെടുക."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mn-rMN/strings.xml b/core/res/res/values-mcc310-mnc260-mn-rMN/strings.xml
new file mode 100644
index 0000000..8b311ee
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-mn-rMN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi Calling одоогоор боломжгүй байна. Wi-Fi Calling  идэвхжүүлэхийн тулд оператортойгоо холбогдоно уу."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mr-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-mr-rIN/strings.xml
new file mode 100644
index 0000000..e191a68
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-mr-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"वाय-फाय कॉलिंग उपलब्‍ध नाही. वाय-फाय कॉलिंग सक्षम करण्‍यासाठी आपल्‍या वाहकाशी संपर्क साधा."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nb/strings.xml b/core/res/res/values-mcc310-mnc260-nb/strings.xml
new file mode 100644
index 0000000..7ece702
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-nb/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi-anrop er ikke tilgjengelig. Ta kontakt med operatøren din for å slå på Wi-Fi-anrop."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ne-rNP/strings.xml b/core/res/res/values-mcc310-mnc260-ne-rNP/strings.xml
index 532cf17..72f94f3 100644
--- a/core/res/res/values-mcc310-mnc260-ne-rNP/strings.xml
+++ b/core/res/res/values-mcc310-mnc260-ne-rNP/strings.xml
@@ -23,6 +23,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorMessages">
-    <item msgid="931634632269046788">"Wi-Fi कलिङ् उपलब्ध छैन। Wi-Fi कलिङ सक्षम पार्न तपाईँको वाहकलाई सम्पर्क गर्नुहोस्।"</item>
+    <item msgid="931634632269046788">"Wi-Fi कलिङ उपलब्ध छैन। Wi-Fi कलिङ सक्षम पार्न तपाईँको वाहकलाई सम्पर्क गर्नुहोस्।"</item>
   </string-array>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
new file mode 100644
index 0000000..1fbe404
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-nl/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Bellen via wifi is niet beschikbaar. Neem contact op met uw provider om bellen via wifi in te schakelen."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pl/strings.xml b/core/res/res/values-mcc310-mnc260-pl/strings.xml
new file mode 100644
index 0000000..41bb1e6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-pl/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Połączenia przez Wi-Fi są niedostępne. Skontaktuj się z operatorem sieci, by je włączyć."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ru/strings.xml b/core/res/res/values-mcc310-mnc260-ru/strings.xml
new file mode 100644
index 0000000..eeceb7c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ru/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Звонки по Wi-Fi недоступны. Чтобы включить эту функцию, свяжитесь со своим оператором."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-si-rLK/strings.xml b/core/res/res/values-mcc310-mnc260-si-rLK/strings.xml
new file mode 100644
index 0000000..dd4da30
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-si-rLK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi ඇමතීම ලබාගත නොහැක. Wi-Fi ඇමතීම ක්‍රියාත්මක කිරීමට ඔබගේ වාහකයා සම්බන්ධ කරගන්න."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sl/strings.xml b/core/res/res/values-mcc310-mnc260-sl/strings.xml
new file mode 100644
index 0000000..2dc873b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-sl/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Klicanje prek Wi-Fi-ja ni na voljo. Obrnite se na operaterja, da vam omogoči klicanje prek Wi-Fi-ja."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sr/strings.xml b/core/res/res/values-mcc310-mnc260-sr/strings.xml
new file mode 100644
index 0000000..76f8aef
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-sr/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Позивање преко Wi-Fi-ја није доступно. Контактирајте мобилног оператера да бисте омогућили позивање преко Wi-Fi-ја."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ta-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-ta-rIN/strings.xml
new file mode 100644
index 0000000..d8b3130
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ta-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"வைஃபை அழைப்பு கிடைக்கவில்லை. வைஃபை அழைப்பை இயக்க, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-te-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-te-rIN/strings.xml
new file mode 100644
index 0000000..ffbab18
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-te-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi కాలింగ్ అందుబాటులో లేదు. Wi-Fi కాలింగ్‌ను ప్రారంభించడానికి మీ క్యారియర్‌ను సంప్రదించండి."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tl/strings.xml b/core/res/res/values-mcc310-mnc260-tl/strings.xml
new file mode 100644
index 0000000..52d97a87
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-tl/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Hindi available ang Pagtawag sa pamamagitan ng Wi-Fi. Makipag-ugnayan sa iyong carrier upang i-enable ang Pagtawag sa pamamagitan ng Wi-Fi."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tr/strings.xml b/core/res/res/values-mcc310-mnc260-tr/strings.xml
new file mode 100644
index 0000000..b28702b82
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-tr/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Kablosuz Çağrı kullanılamıyor. Kablosuz Çağrı özelliğini etkinleştirmek için operatörünüzle iletişim kurun."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ur-rPK/strings.xml b/core/res/res/values-mcc310-mnc260-ur-rPK/strings.xml
new file mode 100644
index 0000000..77ee52b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-ur-rPK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"‏Wi-Fi کالنگ دستیاب نہیں ہے۔ Wi-Fi کالنگ فعال کرنے کیلئے اپنے کیریئر سے رابطہ کریں۔"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uz-rUZ/strings.xml b/core/res/res/values-mcc310-mnc260-uz-rUZ/strings.xml
new file mode 100644
index 0000000..1cd4795
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-uz-rUZ/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Wi-Fi qo‘ng‘iroq mavjud emas. Wi-Fi qo‘ng‘iroqni yoqish uchun tarmoq operatori bilan bog‘laning."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-vi/strings.xml b/core/res/res/values-mcc310-mnc260-vi/strings.xml
new file mode 100644
index 0000000..d47da6d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-vi/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"Tính năng Gọi qua Wi-Fi không khả dụng. Hãy liên hệ với nhà cung cấp dịch vụ để bật tính năng Gọi qua Wi-Fi."</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
new file mode 100644
index 0000000..561484e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"WLAN 通话功能不可用。请与您的运营商联系,以便启用 WLAN 通话功能。"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
new file mode 100644
index 0000000..d93be6d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"無法使用 Wi-Fi 通話。請聯絡您的流動網絡供應商,以啟用 Wi-Fi 通話。"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
new file mode 100644
index 0000000..3acfb84
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2015, 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 my 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorMessages">
+    <item msgid="931634632269046788">"無法使用 Wi-Fi 通話功能。請與您的行動通訊業者聯絡,為您啟用 Wi-Fi 通話功能。"</item>
+  </string-array>
+</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index aa9666f..2080d50 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Банерот со роаминг е вклучен"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Банерот со роаминг е исклучен"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Пребарување за услуга"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Повикување преку Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е препратено"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Асистенција"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помош"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заклучи сега"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="one">Отворени Wi-Fi мрежи се достапни</item>
       <item quantity="other">Отворени Wi-Fi мрежи се достапни</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Најавете се на мрежа на Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не можеше да се поврзе со Wi-Fi"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 6029b7d..2ae1177 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"റോമിംഗ് ബാനർ ഓണാക്കുക"</string>
     <string name="roamingText12" msgid="1189071119992726320">"റോമിംഗ് ബാനർ ഓഫാക്കുക"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"സേവനത്തിനായി തിരയുന്നു"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi കോളിംഗ്"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: കൈമാറിയില്ല"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"അസിസ്റ്റ്"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്‌സ് സഹായം"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ഇപ്പോൾ ലോക്കുചെയ്യുക"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">ലഭ്യമായ Wi-Fi നെറ്റ്‌വർക്കുകൾ തുറക്കുക</item>
       <item quantity="one">ലഭ്യമായ Wi-Fi നെറ്റ്‌വർക്ക് തുറക്കുക</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-ലേക്ക് കണക്‌റ്റുചെയ്യാൻ കഴിഞ്ഞില്ല"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index fb5a47c..4a8b5b9 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Рүүминг Баннер Асаалттай"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Баннергүй рүүминг"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: дамжуулагдаагүй"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"Туслах"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дуут туслах"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Одоо түгжих"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-д холбогдож чадсангүй"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 0318477..3fc5663 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"रोमिंग बॅनर चालू"</string>
     <string name="roamingText12" msgid="1189071119992726320">"रोमिंग बॅनर बंद"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा शोधत आहे"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाय-फाय कॉलिंग"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित केला नाही"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"सहाय्यता"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"आता लॉक करा"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="one">खुले वाय-फाय नेटवर्क उपलब्ध</item>
       <item quantity="other">खुले वाय-फाय नेटवर्क उपलब्ध</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाय-फाय ला कनेक्ट करू शकलो नाही"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 9a80da8..d849680 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mod Pesawat DIHIDUPKAN"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mod Pesawat DIMATIKAN"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Tetapan"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Bantu"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index cb46c91..36a6cde 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"အကူအညီ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"အသံ အကူအညီ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1d1373c..022bb16 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Roaming-banner på"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Roaming-banner av"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Leter etter tjeneste"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-anrop"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ikke viderekoblet"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flymodus er på"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flymodus er av"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Innstillinger"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Hjelp"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nå"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Åpent Wi-Fi-nettverk er tilgjengelig</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logg på Wi-Fi-nettverket"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan ikke koble til Wi-Fi"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 7f47246..54fe0e5 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -123,7 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"रोमिङ ध्वजा चालु छ"</string>
     <string name="roamingText12" msgid="1189071119992726320">"रोमिङ ब्यानर बन्द छ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</string>
-    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ्"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अगाडि पठाइएको छैन"</string>
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"सहायता दिनुहोस्"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अब बन्द गर्नुहोस्"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1fe6424..3318bff 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Roamingbanner aan"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Roamingbanner uit"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Service zoeken"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Bellen via wifi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: niet doorgeschakeld"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Vliegtuigmodus is AAN"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Vliegtuigmodus is UIT"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Instellingen"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Helpen"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Spraakassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Nu vergrendelen"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Open wifi-netwerk beschikbaar</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inloggen bij wifi-netwerk"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan geen verbinding maken met wifi"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0304e8f..4e56e90 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -125,8 +125,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Baner roamingu włączony"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Baner roamingu wyłączony"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Wyszukiwanie usługi"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Połączenia przez Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nieprzekierowane"</string>
@@ -206,6 +205,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Tryb samolotowy jest włączony"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Tryb samolotowy jest wyłączony"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Ustawienia"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pomoc"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asystent głosowy"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
@@ -1316,8 +1316,7 @@
       <item quantity="one">Dostępna jest otwarta sieć Wi-Fi</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Zaloguj się w sieci Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nie można połączyć się z siecią Wi-Fi."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 39ae51c..1ddef71 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"O modo de voo está ativado"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"O modo de voo está desativado"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Definições"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistência"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3a22dd3..35ae345 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avião ATIVADO"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avião DESATIVADO"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Configurações"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Assistência"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 722b59a..360b966 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -204,6 +204,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modul Avion este ACTIVAT"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modul avion este DEZACTIVAT"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Setări"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asistență"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistent vocal"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blocați acum"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 120a9e5..5aa3b39 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -125,8 +125,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Баннер роуминга включен"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Баннер роуминга выключен"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Поиск службы"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Звонки по Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не переадресовано"</string>
@@ -206,6 +205,7 @@
     <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_assist" msgid="3892832961594295030">"Помощник"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Аудиоподсказки"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заблокировать"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
@@ -1316,8 +1316,7 @@
       <item quantity="other">Есть открытые сети Wi-Fi</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Подключение к Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не удалось подключиться к сети Wi-Fi"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 3ea2c73..8a83db9 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"රෝමිං  බැනරය සක්‍රීයයි"</string>
     <string name="roamingText12" msgid="1189071119992726320">"රෝමිං බැනරය අක්‍රියයි"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ඇමතීම"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ඉදිරියට නොයවන ලදි"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"සහාය දීම"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"හඬ සහායක"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"දැන් අගුළු දමන්න"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1304,8 +1304,7 @@
       <item quantity="other">විවෘත Wi-Fi ජාල තිබේ</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ජාලයට පුරනය වන්න"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi වෙත සම්බන්ධ විය නොහැක"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fefc92e..676ffe2 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -205,6 +205,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim v lietadle je ZAPNUTÝ"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim v lietadle je VYPNUTÝ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Nastavenia"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pomôcť"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlasový asistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Uzamknúť"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0c13a51..07d4bb7 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -125,8 +125,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Pasica gostovanja je vklopljena"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Pasica za gostovanje je izklopljena"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Iskanje storitve"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Klicanje prek Wi-Fi-ja"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ni posredovano"</string>
@@ -206,6 +205,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Način za letalo je VKLOPLJEN"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Način za letalo je IZKLOPLJEN"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Nastavitve"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pomoč"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zakleni zdaj"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
@@ -1316,8 +1316,7 @@
       <item quantity="other">Na voljo so odprta omrežja Wi-Fi</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavite se v omrežje Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Z omrežjem Wi-Fi se ni mogoče povezati"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e0e0cc2..54da9a4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -124,8 +124,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Банер роминга је укључен"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Банер роминга је искључен"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Претраживање услуге"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Позивање преко Wi-Fi-ја"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
@@ -205,6 +204,7 @@
     <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_assist" msgid="3892832961594295030">"Помоћ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помоћ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Закључај одмах"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1309,8 +1309,7 @@
       <item quantity="other">Отворене Wi-Fi мреже су доступне</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Пријављивање на Wi-Fi мрежу"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Није могуће повезати са Wi-Fi мрежом"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 450b2ff..dd8a883 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flygplansläge är AKTIVERAT"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flygplansläge är INAKTIVERAT"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Inställningar"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Hjälp"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 129287d..cfa56de 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hali ya ndege IMEWASHWA"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hali ya ndege IMEZIMWA"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Mipangilio"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Mapendekezo"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Usaidizi wa Sauti"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index b23accb..0e5bf3c 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"ரோமிங் பேனர் இயக்கத்தில் உள்ளது"</string>
     <string name="roamingText12" msgid="1189071119992726320">"ரோமிங் பேனர் முடக்கப்பட்டது"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"வைஃபை அழைப்பு"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: பகிரப்படவில்லை"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"உதவி"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"இப்போது பூட்டு"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">பொது வைஃபை நெட்வொர்க்குகள் உள்ளன</item>
       <item quantity="one">பொது வைஃபை நெட்வொர்க் உள்ளது</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"வைஃபை உடன் இணைக்க முடியவில்லை"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index c450e88..4684adf 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"రోమింగ్ బ్యానర్ ఆన్‌లో ఉంది"</string>
     <string name="roamingText12" msgid="1189071119992726320">"రోమింగ్ బ్యానర్ ఆఫ్‌లో ఉంది"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi కాలింగ్"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ఫార్వార్డ్ చేయబడలేదు"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"సహాయం"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ సహాయకం"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">ఓపెన్ Wi-Fi నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి</item>
       <item quantity="one">ఓపెన్ Wi-Fi నెట్‌వర్క్ అందుబాటులో ఉంది</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiకి కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0c73ea1f..39be8c7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -203,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"ผู้ช่วย"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ตัวช่วยเสียง"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ล็อกเลย"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index a70056a..95a1480 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Naka-on ang Banner ng Roaming"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Naka-off ang Banner ng Roaming"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Naghahanap ng Serbisyo"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pagtawag sa pamamagitan ng Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Hindi naipasa"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Naka-ON ang airplane mode"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Naka-OFF ang airplane mode"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Mga Setting"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Tulong"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"I-lock ngayon"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="other">Available ang mga bukas na Wi-Fi network</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Mag-sign in sa Wi-Fi network"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Hindi makakonekta sa Wi-Fi"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7f2fa83..373ef66 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Dolaşım Başlığı Açık"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Dolaşım Başlığı Kapalı"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Hizmet Aranıyor"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Kablosuz Çağrı"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönlendirilmedi"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uçak modu AÇIK"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Uçak modu KAPALI"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Ayarlar"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Asist"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Şimdi kilitle"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Kullanılabilir Kablosuz ağı aç</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kablosuz ağda oturum açın"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kablosuz bağlantısı kurulamadı"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a865f92..c3cfe6d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -205,6 +205,7 @@
     <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_assist" msgid="3892832961594295030">"Підказки"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Голос. підказки"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Блокувати зараз"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 51a7eb7..f315112 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"رومنگ بینر آن ہے"</string>
     <string name="roamingText12" msgid="1189071119992726320">"رومنگ بینر آف"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"سروس کی تلاش کر رہا ہے"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"‏Wi-Fi کالنگ"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : فارورڈ نہیں کی گئی"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"اسسٹ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ابھی مقفل کریں"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"‎999+‎"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">‏عوامی Wi-Fi نیٹ ورکس دستیاب ہیں</item>
       <item quantity="one">‏عوامی Wi-Fi نیٹ ورک دستیاب ہے</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"‏Wi-Fi سے مربوط نہیں ہو سکا"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 0af6f7d..78bad61 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Rouming banneri yoqilgan"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Rouming banneri o‘chirilgan"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Xizmatlar qidirilmoqda"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi qo‘ng‘iroq"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yo‘naltirilmadi"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Parvoz usuli yoqilgan"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Parvoz rejimi o‘chirilgan"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Sozlamalar"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Yordam"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ovozli yordam"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Qulflash"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1301,10 +1301,8 @@
       <item quantity="other">Ochiq Wi-Fi tarmoqlari mavjud</item>
       <item quantity="one">Ochiq Wi-Fi tarmog‘i mavjud</item>
     </plurals>
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi’ga ulana olmadi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7513d5a..a2ebfd4 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"Biểu ngữ Chuyển vùng Bật"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Biểu ngữ Chuyển vùng Tắt"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Đang tìm kiếm Dịch vụ"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Gọi qua Wi-Fi"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Không được chuyển tiếp"</string>
@@ -204,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Chế độ trên máy bay BẬT"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Chế độ trên máy bay TẮT"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Cài đặt"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Hỗ trợ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Khóa ngay"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">Mở mạng Wi-Fi khả dụng</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Đăng nhập vào mạng Wi-Fi"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Không thể kết nối với Wi-Fi"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4a3a7c5..e7c6bee 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"启用漫游横幅"</string>
     <string name="roamingText12" msgid="1189071119992726320">"禁用漫游横幅"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN 通话"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"助理"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">有可用的开放 WLAN 网络</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登录到WLAN网络"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到WLAN"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e927ca5..a62cf11 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"漫遊橫幅開啟"</string>
     <string name="roamingText12" msgid="1189071119992726320">"漫遊橫幅關閉"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"協助"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">有可用的公開 Wi-Fi 網絡</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網絡"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a30ae97..5d1821a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -123,8 +123,7 @@
     <string name="roamingText11" msgid="4154476854426920970">"漫遊橫幅開啟"</string>
     <string name="roamingText12" msgid="1189071119992726320">"漫遊橫幅關閉"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string>
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string>
   <string-array name="wfcOperatorErrorMessages">
   </string-array>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:未轉接"</string>
@@ -204,6 +203,7 @@
     <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_assist" msgid="3892832961594295030">"協助"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
@@ -1302,8 +1302,7 @@
       <item quantity="one">有多個可用的開放 Wi-Fi 網路</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網路"</string>
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f905a91..4c3a400 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -203,6 +203,7 @@
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Imodi yendiza IVULIWE"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Imodi yendiza IVALIWE"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Izilungiselelo"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Siza"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Isisekeli sezwi"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Khiya manje"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 15797dd..b5576c5 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1036,7 +1036,7 @@
         <attr name="colorSwitchThumbNormal" format="color" />
 
         <!-- @hide The background used by framework controls. -->
-        <attr name="controlBackground" format="color" />
+        <attr name="controlBackground" format="reference" />
 
         <!-- The color applied to the edge effect on scrolling containers. -->
         <attr name="colorEdgeEffect" format="color" />
@@ -4443,46 +4443,42 @@
     </declare-styleable>
 
     <declare-styleable name="DatePicker">
-        <!-- The first year (inclusive), for example "1940".
-             {@deprecated Use minDate instead.} -->
+        <!-- The first year (inclusive), for example "1940". {@deprecated Use minDate instead.} -->
         <attr name="startYear" format="integer" />
-        <!-- The last year (inclusive), for example "2010".
-             {@deprecated Use maxDate instead.} -->
+        <!-- The last year (inclusive), for example "2010". {@deprecated Use maxDate instead.} -->
         <attr name="endYear" format="integer" />
-        <!-- Whether the spinners are shown. -->
-        <attr name="spinnersShown" format="boolean" />
-        <!-- Whether the calendar view is shown. -->
-        <attr name="calendarViewShown" format="boolean" />
+
+        <!-- The first day of week according to {@link java.util.Calendar}. -->
+        <attr name="firstDayOfWeek" />
         <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="minDate" format="string" />
         <!-- The maximal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="maxDate" format="string" />
-        <!-- The first day of week according to {@link java.util.Calendar}. -->
-        <attr name="firstDayOfWeek" />
+
+        <!-- Whether the spinners are shown. Only valid for "spinner" mode. -->
+        <attr name="spinnersShown" format="boolean" />
+        <!-- Whether the calendar view is shown. Only valid for "spinner" mode. -->
+        <attr name="calendarViewShown" format="boolean" />
+
         <!-- @hide The layout of the date picker. -->
         <attr name="internalLayout" format="reference"  />
         <!-- @hide The layout of the legacy DatePicker. -->
         <attr name="legacyLayout" />
-        <!-- The background color for the date selector 's day of week. -->
-        <attr name="dayOfWeekBackground" format="color|reference" />
-        <!-- The text color for the date selector's day of week. -->
-        <attr name="dayOfWeekTextAppearance" format="reference" />
-        <!-- The month's text appearance in the date selector. -->
-        <attr name="headerMonthTextAppearance" format="reference" />
-        <!-- The day of month's text appearance in the date selector. -->
-        <attr name="headerDayOfMonthTextAppearance" format="reference" />
-        <!-- The year's text appearance in the date selector. -->
-        <attr name="headerYearTextAppearance" format="reference" />
-        <!-- The background for the date selector. -->
+
+        <!-- The text color for the selected date header text, ex. "2014" or
+             "Tue, Mar 18". This should be a color state list where the
+             activated state will be used when the year picker or day picker is
+             active.-->
+        <attr name="headerTextColor" format="color" />
+        <!-- The background for the selected date header. -->
         <attr name="headerBackground" />
+
         <!-- The list year's text appearance in the list. -->
         <attr name="yearListItemTextAppearance" format="reference" />
-        <!-- The list year's selected circle color in the list. -->
-        <attr name="yearListSelectorColor" format="color" />
+        <!-- @hide The list year's text appearance in the list when activated. -->
+        <attr name="yearListItemActivatedTextAppearance" format="reference" />
         <!-- The text color list of the calendar. -->
         <attr name="calendarTextColor" format="color" />
-        <!-- @hide The activated background color for the calendar. -->
-        <attr name="calendarDayBackgroundColor" format="color" />
         <!-- Defines the look of the widget. Prior to the L release, the only choice was
              spinner. As of L, with the Material theme selected, the default layout is calendar,
              but this attribute can be used to force spinner to be used instead. -->
@@ -4492,6 +4488,19 @@
             <!-- Date picker with calendar to select the date. -->
             <enum name="calendar" value="2" />
         </attr>
+
+        <!-- @deprecated The text appearance for the month (ex. May) in the selected date header. -->
+        <attr name="headerMonthTextAppearance" format="reference" />
+        <!-- @deprecated The text appearance for the day of month (ex. 28) in the selected date header. -->
+        <attr name="headerDayOfMonthTextAppearance" format="reference" />
+        <!-- The text appearance for the year (ex. 2014) in the selected date header. -->
+        <attr name="headerYearTextAppearance" format="reference" />
+        <!-- @deprecated The background color for the header's day of week. -->
+        <attr name="dayOfWeekBackground" format="color" />
+        <!-- @deprecated The text color for the header's day of week. -->
+        <attr name="dayOfWeekTextAppearance" format="reference" />
+        <!-- @deprecated The list year's selected circle color in the list. -->
+        <attr name="yearListSelectorColor" format="color" />
     </declare-styleable>
 
     <declare-styleable name="TwoLineListItem">
@@ -4709,35 +4718,42 @@
     <declare-styleable name="CalendarView">
         <!-- The first day of week according to {@link java.util.Calendar}. -->
         <attr name="firstDayOfWeek" format="integer" />
-        <!-- Whether do show week numbers. -->
-        <attr name="showWeekNumber" format="boolean" />
         <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="minDate" />
         <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="maxDate" />
-        <!-- The number of weeks to be shown. -->
-        <attr name="shownWeekCount" format="integer"/>
-        <!-- The background color for the selected week. -->
-        <attr name="selectedWeekBackgroundColor" format="color|reference" />
-        <!-- The color for the dates of the focused month. -->
-        <attr name="focusedMonthDateColor" format="color|reference" />
-        <!-- The color for the dates of an unfocused month. -->
-        <attr name="unfocusedMonthDateColor" format="color|reference" />
-        <!-- The color for the week numbers. -->
-        <attr name="weekNumberColor" format="color|reference" />
-        <!-- The color for the separator line between weeks. -->
-        <attr name="weekSeparatorLineColor" format="color|reference" />
-        <!-- Drawable for the vertical bar shown at the beginning and at the end of the selected date. -->
-        <attr name="selectedDateVerticalBar" format="reference" />
-        <!-- The text appearance for the week day abbreviation of the calendar header. -->
+        <!-- The text appearance for the month and year in the calendar header. -->
+        <attr name="monthTextAppearance" format="reference" />
+        <!-- The text appearance for the week day abbreviation in the calendar header. -->
         <attr name="weekDayTextAppearance" format="reference" />
-        <!-- The text appearance for the calendar dates. -->
+        <!-- The text appearance for the day numbers in the calendar grid. -->
         <attr name="dateTextAppearance" format="reference" />
-        <!-- The number of weeks to be shown. -->
+        <!-- @hide The background color used for the day selection indicator. -->
+        <attr name="daySelectorColor" format="color" />
+        <!-- @hide The background color used for the day highlight indicator. -->
+        <attr name="dayHighlightColor" format="color" />
+        <!-- @hide Which style of calendar delegate to use. -->
         <attr name="calendarViewMode">
             <enum name="holo" value="0" />
             <enum name="material" value="1" />
         </attr>
+
+        <!-- @deprecated Whether do show week numbers. -->
+        <attr name="showWeekNumber" format="boolean" />
+        <!-- @deprecated The number of weeks to be shown. -->
+        <attr name="shownWeekCount" format="integer"/>
+        <!-- @deprecated The background color for the selected week. -->
+        <attr name="selectedWeekBackgroundColor" format="color|reference" />
+        <!-- @deprecated The color for the dates of the focused month. -->
+        <attr name="focusedMonthDateColor" format="color|reference" />
+        <!-- @deprecated The color for the dates of an unfocused month. -->
+        <attr name="unfocusedMonthDateColor" format="color|reference" />
+        <!-- @deprecated The color for the week numbers. -->
+        <attr name="weekNumberColor" format="color|reference" />
+        <!-- @deprecated The color for the separator line between weeks. -->
+        <attr name="weekSeparatorLineColor" format="color|reference" />
+        <!-- @deprecated Drawable for the vertical bar shown at the beginning and at the end of the selected date. -->
+        <attr name="selectedDateVerticalBar" format="reference" />
     </declare-styleable>
 
     <declare-styleable name="NumberPicker">
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index c0b2cbef..aefb67c 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1039,6 +1039,10 @@
          activity. -->
     <attr name="resizeableActivity" format="boolean" />
 
+    <!-- When set installer will extract native libraries. If set to false
+         libraries in the apk must be stored and page-aligned.  -->
+    <attr name="extractNativeLibs" format="boolean"/>
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -1169,8 +1173,8 @@
              @hide -->
         <attr name="usesCleartextTraffic" />
         <attr name="multiArch" />
+        <attr name="extractNativeLibs" />
     </declare-styleable>
-    
     <!-- The <code>permission</code> tag declares a security permission that can be
          used to control access from other packages to specific components or
          features in your package (or other packages).  See the
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index da68c92..1cb39f0 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -16,16 +16,19 @@
 
 <!-- Colors specific to Material themes. -->
 <resources>
-    <color name="background_material_dark">#ff303030</color>
-    <color name="background_material_light">#fffafafa</color>
-    <color name="background_floating_material_dark">#ff424242</color>
-    <color name="background_floating_material_light">#ffffffff</color>
+    <color name="foreground_material_dark">@color/white</color>
+    <color name="foreground_material_light">@color/black</color>
 
-    <color name="primary_material_dark">#ff212121</color>
-    <color name="primary_material_light">#fff5f5f5</color>
-    <color name="primary_dark_material_dark">#ff000000</color>
-    <color name="primary_dark_material_light">#ff757575</color>
-    <color name="primary_dark_material_light_light_status_bar">#ffe0e0e0</color>
+    <color name="background_material_dark">@color/material_grey_850</color>
+    <color name="background_material_light">@color/material_grey_50</color>
+    <color name="background_floating_material_dark">@color/material_grey_800</color>
+    <color name="background_floating_material_light">@color/white</color>
+
+    <color name="primary_material_dark">@color/material_grey_900</color>
+    <color name="primary_material_light">@color/material_grey_100</color>
+    <color name="primary_dark_material_dark">@color/black</color>
+    <color name="primary_dark_material_light">@color/material_grey_600</color>
+    <color name="primary_dark_material_light_light_status_bar">@color/material_grey_300</color>
 
     <color name="accent_material_light">@color/material_deep_teal_500</color>
     <color name="accent_material_dark">@color/material_deep_teal_200</color>
@@ -38,19 +41,20 @@
     <color name="switch_thumb_disabled_material_dark">#ff616161</color>
     <color name="switch_thumb_disabled_material_light">#ffbdbdbd</color>
 
-    <color name="foreground_material_dark">@color/white</color>
-    <color name="foreground_material_light">@color/black</color>
-
-    <color name="link_text_material_dark">@color/material_deep_teal_200</color>
     <color name="link_text_material_light">@color/material_deep_teal_500</color>
+    <color name="link_text_material_dark">@color/material_deep_teal_200</color>
 
     <!-- Text & foreground colors -->
     <eat-comment />
 
+    <!-- 87% black -->
     <color name="primary_text_default_material_light">#de000000</color>
+    <!-- 54% black -->
     <color name="secondary_text_default_material_light">#8a000000</color>
 
+    <!-- 100% white -->
     <color name="primary_text_default_material_dark">#ffffffff</color>
+    <!-- 70% white -->
     <color name="secondary_text_default_material_dark">#b3ffffff</color>
 
     <item name="hint_alpha_material_dark" format="float" type="dimen">0.50</item>
@@ -66,6 +70,14 @@
     <!-- Primary & accent colors -->
     <eat-comment />
 
+    <color name="material_grey_900">#ff212121</color>
+    <color name="material_grey_850">#ff303030</color>
+    <color name="material_grey_800">#ff424242</color>
+    <color name="material_grey_600">#ff757575</color>
+    <color name="material_grey_300">#ffe0e0e0</color>
+    <color name="material_grey_100">#fff5f5f5</color>
+    <color name="material_grey_50">#fffafafa</color>
+
     <color name="material_deep_teal_200">#ff80cbc4</color>
     <color name="material_deep_teal_500">#ff009688</color>
 
@@ -98,16 +110,16 @@
     <color name="datepicker_default_disabled_text_color_material_light">#80999999</color>
     <color name="datepicker_default_disabled_text_color_material_dark">#80999999</color>
 
-    <color name="datepicker_default_selected_text_color_material_light">#33b5e5</color>
-    <color name="datepicker_default_selected_text_color_material_dark">#33b5e5</color>
+    <color name="datepicker_default_selected_text_color_material_light">#ff33b5e5</color>
+    <color name="datepicker_default_selected_text_color_material_dark">#ff33b5e5</color>
 
-    <color name="datepicker_default_pressed_text_color_material_light">#0099cc</color>
-    <color name="datepicker_default_pressed_text_color_material_dark">#0099cc</color>
+    <color name="datepicker_default_pressed_text_color_material_light">#ff0099cc</color>
+    <color name="datepicker_default_pressed_text_color_material_dark">#ff0099cc</color>
 
     <color name="datepicker_default_circle_background_color_material_light">@color/material_deep_teal_500</color>
     <color name="datepicker_default_circle_background_color_material_dark">@color/material_deep_teal_200</color>
 
-    <color name="datepicker_default_view_animator_color_material_light">#f2f2f2</color>
+    <color name="datepicker_default_view_animator_color_material_light">#fff2f2f2</color>
     <color name="datepicker_default_view_animator_color_material_dark">#ff303030</color>
 
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 8d2afde..6fd39f6 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -143,9 +143,7 @@
     <dimen name="timepicker_text_size_inner">12sp</dimen>
 
     <!-- Material date picker dimensions. -->
-    <dimen name="datepicker_year_picker_padding_top">8dp</dimen>
     <dimen name="datepicker_year_label_height">64dp</dimen>
-    <dimen name="datepicker_year_label_text_size">22dp</dimen>
     <dimen name="datepicker_component_width">260dp</dimen>
     <dimen name="datepicker_dialog_width">520dp</dimen>
     <dimen name="datepicker_selected_date_day_size">88dp</dimen>
@@ -154,10 +152,24 @@
     <dimen name="datepicker_header_height">30dp</dimen>
     <dimen name="datepicker_header_text_size">14dp</dimen>
 
+    <dimen name="datepicker_list_year_label_size">16sp</dimen>
+    <dimen name="datepicker_list_year_activated_label_size">26sp</dimen>
+
+    <dimen name="date_picker_year_label_size">16sp</dimen>
+    <dimen name="date_picker_date_label_size">34dp</dimen>
+
     <!-- Used by Material-style SimpleMonthView -->
-    <dimen name="datepicker_day_number_size">12sp</dimen>
-    <dimen name="datepicker_month_label_size">14sp</dimen>
-    <dimen name="datepicker_month_day_label_text_size">12sp</dimen>
-    <dimen name="datepicker_month_list_item_header_height">48dp</dimen>
+    <dimen name="date_picker_month_text_size">14sp</dimen>
+    <dimen name="date_picker_day_of_week_text_size">12sp</dimen>
+    <dimen name="date_picker_day_text_size">12sp</dimen>
+    <dimen name="date_picker_month_height">56dp</dimen>
+    <dimen name="date_picker_day_of_week_height">36dp</dimen>
+    <dimen name="date_picker_day_height">40dp</dimen>
+    <dimen name="date_picker_day_width">44dp</dimen>
+    <dimen name="date_picker_day_selector_radius">20dp</dimen>
+    <dimen name="day_picker_padding_horizontal">20dp</dimen>
+    <dimen name="day_picker_padding_top">6dp</dimen>
+    <dimen name="day_picker_button_margin_top">0dp</dimen>
+
     <dimen name="datepicker_view_animator_height">226dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e507b3d..5e4b039 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2651,4 +2651,5 @@
 
   <public type="attr" name="colorBackgroundFloating" />
 
+  <public type="attr" name="extractNativeLibs" />
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 19cae03..7672e93 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5042,18 +5042,6 @@
     <!-- Accessibility announcement for minute circular picker [CHAR LIMIT=NONE] -->
     <string name="select_minutes">Select minutes</string>
 
-    <!--
-        Content description for the month and day selector in the date picker, which displays
-        a selectable grid of days laid out by month.
-        [CHAR LIMIT=50]
-     -->
-    <string name="day_picker_description">Month grid of days</string>
-    <!--
-        Content description for the year selector in the date picker, which displays
-        a scrolling, vertical list of years.
-        [CHAR LIMIT=50]
-     -->
-    <string name="year_picker_description">Year list</string>
     <!-- Accessibility announcement for the day picker [CHAR LIMIT=NONE] -->
     <string name="select_day">Select month and day</string>
     <!-- Accessibility announcement for the year picker [CHAR LIMIT=NONE] -->
@@ -5079,7 +5067,11 @@
     <string name="sans_serif">sans-serif</string>
 
     <!-- DO NOT TRANSLATE -->
-    <string name="day_of_week_label_typeface">sans-serif</string>
+    <string name="date_picker_month_typeface">sans-serif-medium</string>
+    <!-- DO NOT TRANSLATE -->
+    <string name="date_picker_day_of_week_typeface">sans-serif-medium</string>
+    <!-- DO NOT TRANSLATE -->
+    <string name="date_picker_day_typeface">sans-serif-medium</string>
 
     <!-- Notify use that they are in Lock-to-app -->
     <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Overview at the same time.</string>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index a8ab18d..f1f7462 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -372,11 +372,13 @@
     <style name="TextAppearance.Material.WindowTitle" parent="TextAppearance.Material.Title" />
     <style name="TextAppearance.Material.DialogWindowTitle" parent="TextAppearance.Material.Title" />
 
-    <style name="TextAppearance.Material.CalendarViewWeekDayView" parent="TextAppearance.Material.Small">
-        <item name="textStyle">bold</item>
-        <item name="textColor">#505050</item>
+    <style name="TextAppearance.Material.Widget.Calendar.Day" parent="TextAppearance.Material.Caption">
+        <item name="textColor">?attr/textColorPrimaryActivated</item>
     </style>
 
+    <style name="TextAppearance.Material.Widget.Calendar.DayOfWeek" parent="TextAppearance.Material.Caption" />
+    <style name="TextAppearance.Material.Widget.Calendar.Month" parent="TextAppearance.Material.Body2" />
+
     <style name="TextAppearance.Material.TimePicker.TimeLabel" parent="TextAppearance.Material">
         <item name="textSize">@dimen/timepicker_time_label_size</item>
         <item name="textColor">@color/time_picker_header_text_material</item>
@@ -406,14 +408,27 @@
     </style>
 
     <style name="TextAppearance.Material.DatePicker.YearLabel" parent="TextAppearance.Material">
-        <item name="includeFontPadding">false</item>
         <item name="textColor">@color/date_picker_header_text_material</item>
-        <item name="textSize">@dimen/datepicker_selected_date_year_size</item>
+        <item name="textSize">@dimen/date_picker_year_label_size</item>
+        <item name="fontFamily">sans-serif-medium</item>
+    </style>
+
+    <style name="TextAppearance.Material.DatePicker.DateLabel" parent="TextAppearance.Material">
+        <item name="textColor">@color/date_picker_header_text_material</item>
+        <item name="textSize">@dimen/date_picker_date_label_size</item>
+        <item name="fontFamily">sans-serif-medium</item>
     </style>
 
     <style name="TextAppearance.Material.DatePicker.List.YearLabel" parent="TextAppearance.Material">
-        <item name="textColor">?attr/textColorSecondaryActivated</item>
-        <item name="textSize">@dimen/datepicker_year_label_text_size</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">@dimen/datepicker_list_year_label_size</item>
+        <item name="fontFamily">sans-serif</item>
+    </style>
+
+    <style name="TextAppearance.Material.DatePicker.List.YearLabel.Activated">
+        <item name="textColor">?attr/colorControlActivated</item>
+        <item name="textSize">@dimen/datepicker_list_year_activated_label_size</item>
+        <item name="fontFamily">sans-serif-medium</item>
     </style>
 
     <style name="TextAppearance.Material.Notification">
@@ -487,7 +502,8 @@
     <!-- Alert dialog button bar button -->
     <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
         <item name="minWidth">64dp</item>
-        <item name="maxLines">2</item>
+        <item name="singleLine">true</item>
+        <item name="ellipsize">none</item>
         <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
     </style>
 
@@ -615,14 +631,13 @@
     </style>
 
     <style name="Widget.Material.CalendarView" parent="Widget.CalendarView">
-        <item name="selectedWeekBackgroundColor">#330099FF</item>
-        <item name="focusedMonthDateColor">#FFFFFFFF</item>
-        <item name="unfocusedMonthDateColor">#66FFFFFF</item>
-        <item name="weekNumberColor">#33FFFFFF</item>
-        <item name="weekSeparatorLineColor">#19FFFFFF</item>
-        <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
-        <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
         <item name="calendarViewMode">material</item>
+
+        <item name="monthTextAppearance">@style/TextAppearance.Material.Widget.Calendar.Month</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Material.Widget.Calendar.DayOfWeek</item>
+        <item name="dateTextAppearance">@style/TextAppearance.Material.Widget.Calendar.Day</item>
+        <item name="daySelectorColor">?attr/colorControlActivated</item>
+        <item name="dayHighlightColor">?attr/colorControlHighlight</item>
     </style>
 
     <style name="Widget.Material.ImageButton" parent="Widget.ImageButton">
@@ -647,11 +662,11 @@
         <item name="internalLayout">@layout/time_picker_material</item>
         <item name="headerTimeTextAppearance">@style/TextAppearance.Material.TimePicker.TimeLabel</item>
         <item name="headerAmPmTextAppearance">@style/TextAppearance.Material.TimePicker.AmPmLabel</item>
-        <item name="headerBackground">@drawable/time_picker_header_material</item>
+        <item name="headerBackground">#ff555555</item>
         <item name="numbersTextColor">?attr/textColorPrimaryActivated</item>
         <item name="numbersInnerTextColor">?attr/textColorSecondaryActivated</item>
-        <item name="numbersBackgroundColor">#10ffffff</item>
         <item name="numbersSelectorColor">?attr/colorControlActivated</item>
+        <item name="numbersBackgroundColor">#ff555555</item>
         <item name="amPmTextColor">?attr/textColorSecondary</item>
     </style>
 
@@ -660,17 +675,10 @@
         <item name="legacyLayout">@layout/date_picker_legacy_holo</item>
         <item name="calendarViewShown">true</item>
         <!-- Attributes for new-style DatePicker. -->
-        <item name="internalLayout">@layout/date_picker_holo</item>
-        <item name="dayOfWeekBackground">#10000000</item>
-        <item name="dayOfWeekTextAppearance">@style/TextAppearance.Material.DatePicker.DayOfWeekLabel</item>
-        <item name="headerMonthTextAppearance">@style/TextAppearance.Material.DatePicker.MonthLabel</item>
-        <item name="headerDayOfMonthTextAppearance">@style/TextAppearance.Material.DatePicker.DayOfMonthLabel</item>
-        <item name="headerYearTextAppearance">@style/TextAppearance.Material.DatePicker.YearLabel</item>
-        <item name="headerBackground">?attr/colorAccent</item>
+        <item name="internalLayout">@layout/date_picker_material</item>
         <item name="yearListItemTextAppearance">@style/TextAppearance.Material.DatePicker.List.YearLabel</item>
-        <item name="yearListSelectorColor">?attr/colorControlActivated</item>
-        <item name="calendarTextColor">?attr/textColorSecondaryActivated</item>
-        <item name="calendarDayBackgroundColor">?attr/colorControlActivated</item>
+        <item name="yearListItemActivatedTextAppearance">@style/TextAppearance.Material.DatePicker.List.YearLabel.Activated</item>
+        <item name="headerBackground">#ff555555</item>
     </style>
 
     <style name="Widget.Material.ActivityChooserView" parent="Widget.ActivityChooserView">
@@ -1021,24 +1029,18 @@
     <style name="Widget.Material.Light.GestureOverlayView" parent="Widget.Material.GestureOverlayView"/>
     <style name="Widget.Material.Light.GridView" parent="Widget.Material.GridView"/>
     <style name="Widget.Material.Light.ImageButton" parent="Widget.Material.ImageButton"/>
-
-    <style name="Widget.Material.Light.CalendarView" parent="Widget.CalendarView">
-        <item name="selectedWeekBackgroundColor">#330066ff</item>
-        <item name="focusedMonthDateColor">#FF000000</item>
-        <item name="unfocusedMonthDateColor">#7F08002B</item>
-        <item name="weekNumberColor">#7F080021</item>
-        <item name="weekSeparatorLineColor">#7F08002A</item>
-        <item name="weekDayTextAppearance">@style/TextAppearance.Material.CalendarViewWeekDayView</item>
-        <item name="calendarViewMode">material</item>
-    </style>
-
+    <style name="Widget.Material.Light.CalendarView" parent="Widget.Material.CalendarView" />
     <style name="Widget.Material.Light.NumberPicker" parent="Widget.Material.NumberPicker"/>
 
     <style name="Widget.Material.Light.TimePicker" parent="Widget.Material.TimePicker">
-        <item name="numbersBackgroundColor">#10000000</item>
+        <item name="headerBackground">?attr/colorAccent</item>
+        <item name="numbersBackgroundColor">#ffeeeeee</item>
     </style>
 
-    <style name="Widget.Material.Light.DatePicker" parent="Widget.Material.DatePicker" />
+    <style name="Widget.Material.Light.DatePicker" parent="Widget.Material.DatePicker">
+        <item name="headerBackground">?attr/colorAccent</item>
+    </style>
+
     <style name="Widget.Material.Light.ActivityChooserView" parent="Widget.Material.ActivityChooserView" />
     <style name="Widget.Material.Light.ImageWell" parent="Widget.Material.ImageWell"/>
     <style name="Widget.Material.Light.ListView" parent="Widget.Material.ListView"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 203b017..c4e9e8e 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1988,7 +1988,7 @@
   <java-symbol type="layout" name="time_picker_material" />
   <java-symbol type="layout" name="time_picker_header_material" />
   <java-symbol type="layout" name="year_label_text_view" />
-  <java-symbol type="layout" name="date_picker_holo" />
+  <java-symbol type="layout" name="date_picker_material" />
 
   <java-symbol type="id" name="time_header" />
   <java-symbol type="id" name="hours" />
@@ -1999,11 +1999,8 @@
   <java-symbol type="id" name="radial_picker" />
   <java-symbol type="id" name="separator" />
   <java-symbol type="id" name="date_picker_header" />
-  <java-symbol type="id" name="date_picker_month_and_day_layout" />
-  <java-symbol type="id" name="day_picker_selector_layout" />
-  <java-symbol type="id" name="date_picker_month" />
-  <java-symbol type="id" name="date_picker_day" />
-  <java-symbol type="id" name="date_picker_year" />
+  <java-symbol type="id" name="date_picker_header_year" />
+  <java-symbol type="id" name="date_picker_header_date" />
   <java-symbol type="id" name="animator" />
 
   <java-symbol type="string" name="done_label" />
@@ -2039,19 +2036,24 @@
   <java-symbol type="string" name="muted_by" />
 
   <java-symbol type="string" name="item_is_selected" />
-  <java-symbol type="string" name="day_of_week_label_typeface" />
   <java-symbol type="string" name="select_day" />
-  <java-symbol type="string" name="day_picker_description" />
   <java-symbol type="string" name="select_year" />
-  <java-symbol type="string" name="year_picker_description" />
 
-  <java-symbol type="dimen" name="datepicker_day_number_size" />
-  <java-symbol type="dimen" name="datepicker_month_label_size" />
-  <java-symbol type="dimen" name="datepicker_month_day_label_text_size" />
-  <java-symbol type="dimen" name="datepicker_month_list_item_header_height" />
+  <java-symbol type="string" name="date_picker_month_typeface" />
+  <java-symbol type="string" name="date_picker_day_of_week_typeface" />
+  <java-symbol type="string" name="date_picker_day_typeface" />
+  <java-symbol type="dimen" name="date_picker_month_text_size" />
+  <java-symbol type="dimen" name="date_picker_day_of_week_text_size" />
+  <java-symbol type="dimen" name="date_picker_day_text_size" />
+  <java-symbol type="dimen" name="date_picker_month_height" />
+  <java-symbol type="dimen" name="date_picker_day_height" />
+  <java-symbol type="dimen" name="date_picker_day_width" />
+  <java-symbol type="dimen" name="date_picker_day_selector_radius" />
+  <java-symbol type="id" name="date_picker_day_picker" />
+  <java-symbol type="id" name="date_picker_year_picker" />
+
   <java-symbol type="dimen" name="datepicker_view_animator_height" />
   <java-symbol type="dimen" name="datepicker_year_label_height" />
-  <java-symbol type="dimen" name="datepicker_year_picker_padding_top" />
 
   <java-symbol type="array" name="config_clockTickVibePattern" />
   <java-symbol type="array" name="config_calendarDateVibePattern" />
@@ -2115,7 +2117,6 @@
   <java-symbol type="id" name="transitionTransform" />
   <java-symbol type="id" name="parentMatrix" />
   <java-symbol type="bool" name="config_auto_attach_data_on_creation" />
-  <java-symbol type="id" name="date_picker_month_day_year_layout" />
   <java-symbol type="attr" name="closeItemLayout" />
   <java-symbol type="layout" name="resolver_different_item_header" />
   <java-symbol type="array" name="config_default_vm_number" />
@@ -2167,4 +2168,10 @@
   <java-symbol type="integer" name="config_screen_magnification_multi_tap_adjustment" />
   <java-symbol type="dimen" name="config_screen_magnification_scaling_threshold" />
   <java-symbol type="dimen" name="timepicker_selector_stroke"/>
+
+  <java-symbol type="style" name="TextAppearance.Material.Widget.Calendar.Month" />
+  <java-symbol type="style" name="TextAppearance.Material.Widget.Calendar.DayOfWeek" />
+  <java-symbol type="style" name="TextAppearance.Material.Widget.Calendar.Day" />
+  <java-symbol type="dimen" name="day_picker_padding_top"/>
+  <java-symbol type="dimen" name="date_picker_day_of_week_height"/>
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 38cfecd..9931d00 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -857,6 +857,7 @@
     <!-- Theme overlay that overrides window properties to display as a dialog. -->
     <style name="ThemeOverlay.Material.Dialog">
         <item name="colorBackgroundCacheHint">@null</item>
+        <item name="colorBackground">?attr/colorBackgroundFloating</item>
 
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
@@ -1271,7 +1272,6 @@
     <style name="Theme.Material.Settings" parent="Theme.Material.DayNight.DarkActionBar">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
 
         <item name="presentationTheme">@style/Theme.Material.Settings.Dialog.Presentation</item>
         <item name="searchDialogTheme">@style/Theme.Material.Settings.SearchBar</item>
@@ -1281,7 +1281,6 @@
     <style name="Theme.Material.Settings.BaseDialog" parent="Theme.Material.DayNight.BaseDialog">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
     </style>
 
     <style name="Theme.Material.Settings.Dialog" parent="Theme.Material.Settings.BaseDialog" />
@@ -1289,7 +1288,6 @@
     <style name="Theme.Material.Settings.Dialog.BaseAlert" parent="Theme.Material.DayNight.Dialog.BaseAlert">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
     </style>
 
     <style name="Theme.Material.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.BaseAlert" />
@@ -1297,7 +1295,6 @@
     <style name="Theme.Material.Settings.Dialog.Presentation" parent="Theme.Material.DayNight.Dialog.Presentation">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
     </style>
 
     <style name="Theme.Material.Settings.SearchBar" parent="Theme.Material.DayNight.SearchBar">
@@ -1309,6 +1306,5 @@
     <style name="Theme.Material.Settings.CompactMenu" parent="Theme.Material.DayNight.CompactMenu">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
     </style>
 </resources>
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index b61ea8e..7322e8d 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -23,6 +23,14 @@
     libnativehelper
 
 LOCAL_MODULE := libframeworks_coretests_jni
+
+# this does not prevent build system
+# from installing library to /system/lib
 LOCAL_MODULE_TAGS := tests
 
+# .. we want to avoid that... so we put it somewhere
+# bionic linker cant find it without outside help (nativetests):
+LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
index 957fc4a..e0b616c 100644
--- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
+++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
@@ -27,8 +27,8 @@
     { "checkFunction", "()I", (void*) checkFunction },
 };
 
-int register_com_android_framework_coretests_JNITests(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/framework/coretests/JNITests", sMethods,
+int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods,
             NELEM(sMethods));
 }
 
@@ -46,7 +46,7 @@
         return JNI_ERR;
     }
 
-    if ((status = android::register_com_android_framework_coretests_JNITests(e)) < 0) {
+    if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) {
         return JNI_ERR;
     }
 
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
new file mode 100644
index 0000000..5fa2405
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
+
+LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS := -0
+LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
+
+include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml
new file mode 100644
index 0000000..190f894
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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="com.android.frameworks.coretests.install_jni_lib_open_from_apk">
+
+    <application android:hasCode="true" android:label="@string/app_name" android:extractNativeLibs="false">
+        <activity android:name="com.android.frameworks.coretests.OpenFromApkActivity"
+           android:label="@string/app_name">
+          <intent-filter>
+            <action android:name="android.intent.action.MAIN" />
+            <category android:name="android.intent.category.LAUNCHER" />
+          </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/core/res/res/drawable/time_picker_header_material.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml
similarity index 71%
rename from core/res/res/drawable/time_picker_header_material.xml
rename to core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml
index ef2068a..8c2a0bf 100644
--- a/core/res/res/drawable/time_picker_header_material.xml
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="?attr/colorControlHighlight">
-    <item android:drawable="?attr/colorAccent" />
-</ripple>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="app_name">Load From Apk Test</string>
+</resources>
diff --git a/core/java/android/hardware/IProCameraUser.aidl b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java
similarity index 70%
rename from core/java/android/hardware/IProCameraUser.aidl
rename to core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java
index eacb0f4..4f9176c 100644
--- a/core/java/android/hardware/IProCameraUser.aidl
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -12,15 +12,15 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
  */
 
-package android.hardware;
+package com.android.frameworks.coretests;
 
-/** @hide */
-interface IProCameraUser
-{
-    /**
-     * Keep up-to-date with frameworks/av/include/camera/IProCameraUser.h
-     */
-    void disconnect();
+public class JNITests {
+  static {
+    System.loadLibrary("frameworks_coretests_jni");
+  }
+
+  public static native int checkFunction();
 }
diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java
new file mode 100644
index 0000000..524cad7c
--- /dev/null
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java
@@ -0,0 +1,38 @@
+/*
+ * 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.frameworks.coretests;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class OpenFromApkActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        TextView  tv = new TextView(this);
+
+        int i = JNITests.checkFunction();
+
+        tv.setText("All is well: i=" + i);
+
+        setContentView(tv);
+    }
+
+}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 6659769..c517201 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -58,11 +58,11 @@
         <group gid="log" />
     </permission>
 
-    <permission name="android.permission.READ_EXTERNAL_STORAGE" >
+    <permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
         <group gid="sdcard_r" />
     </permission>
 
-    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
+    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
         <group gid="sdcard_r" />
         <group gid="sdcard_rw" />
     </permission>
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index a213af8..1d6c60f 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -275,7 +275,7 @@
 
     @Override
     protected boolean onStateChange(int[] state) {
-        if (mDrawable != null) {
+        if (mDrawable != null && mDrawable.isStateful()) {
             final boolean changed = mDrawable.setState(state);
             if (changed) {
                 onBoundsChange(getBounds());
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 74f62be..30fbe16 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -17,6 +17,7 @@
 package android.graphics.drawable;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
@@ -98,24 +99,29 @@
     private boolean mMutated;
 
     /**
-     * Create a new layer drawable with the list of specified layers.
+     * Creates a new layer drawable with the list of specified layers.
      *
-     * @param layers A list of drawables to use as layers in this new drawable.
+     * @param layers a list of drawables to use as layers in this new drawable,
+     *               must be non-null
      */
-    public LayerDrawable(Drawable[] layers) {
+    public LayerDrawable(@NonNull Drawable[] layers) {
         this(layers, null);
     }
 
     /**
-     * Create a new layer drawable with the specified list of layers and the
+     * Creates a new layer drawable with the specified list of layers and the
      * specified constant state.
      *
      * @param layers The list of layers to add to this drawable.
      * @param state The constant drawable state.
      */
-    LayerDrawable(Drawable[] layers, LayerState state) {
+    LayerDrawable(@NonNull Drawable[] layers, @Nullable LayerState state) {
         this(state, null);
 
+        if (layers == null) {
+            throw new IllegalArgumentException("layers must be non-null");
+        }
+
         final int length = layers.length;
         final ChildDrawable[] r = new ChildDrawable[length];
         for (int i = 0; i < length; i++) {
@@ -134,14 +140,14 @@
         this((LayerState) null, null);
     }
 
-    LayerDrawable(LayerState state, Resources res) {
+    LayerDrawable(@Nullable LayerState state, @Nullable Resources res) {
         mLayerState = createConstantState(state, res);
         if (mLayerState.mNum > 0) {
             ensurePadding();
         }
     }
 
-    LayerState createConstantState(LayerState state, Resources res) {
+    LayerState createConstantState(@Nullable LayerState state, @Nullable Resources res) {
         return new LayerState(state, this, res);
     }
 
@@ -393,6 +399,7 @@
     public int addLayer(Drawable dr) {
         final ChildDrawable layer = createLayer(dr);
         final int index = addLayer(layer);
+        ensurePadding();
         return index;
     }
 
@@ -1107,7 +1114,6 @@
 
     @Override
     protected boolean onStateChange(int[] state) {
-        boolean paddingChanged = false;
         boolean changed = false;
 
         final ChildDrawable[] array = mLayerState.mChildren;
@@ -1115,15 +1121,12 @@
         for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.isStateful() && r.mDrawable.setState(state)) {
+                refreshChildPadding(i, r);
                 changed = true;
             }
-
-            if (refreshChildPadding(i, r)) {
-                paddingChanged = true;
-            }
         }
 
-        if (paddingChanged) {
+        if (changed) {
             updateLayerBounds(getBounds());
         }
 
@@ -1132,7 +1135,6 @@
 
     @Override
     protected boolean onLevelChange(int level) {
-        boolean paddingChanged = false;
         boolean changed = false;
 
         final ChildDrawable[] array = mLayerState.mChildren;
@@ -1140,15 +1142,12 @@
         for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.setLevel(level)) {
+                refreshChildPadding(i, r);
                 changed = true;
             }
-
-            if (refreshChildPadding(i, r)) {
-                paddingChanged = true;
-            }
         }
 
-        if (paddingChanged) {
+        if (changed) {
             updateLayerBounds(getBounds());
         }
 
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index c5e53da..39a33ce 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -805,7 +805,6 @@
         // is no need for deep copying.
         private final Path mPath;
         private final Path mRenderPath;
-        private static final Matrix IDENTITY_MATRIX = new Matrix();
         private final Matrix mFinalPathMatrix = new Matrix();
 
         private Paint mStrokePaint;
@@ -948,7 +947,7 @@
 
         public void draw(Canvas canvas, int w, int h, ColorFilter filter) {
             // Travese the tree in pre-order to draw.
-            drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h, filter);
+            drawGroupTree(mRootGroup, Matrix.IDENTITY_MATRIX, canvas, w, h, filter);
         }
 
         private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h,
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 8673219..65160d5 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1195,6 +1195,12 @@
     // Example: en-US, en-Latn-US, en-POSIX.
     void getBcp47Locale(char* out) const;
 
+    // Append to str the resource-qualifer string representation of the
+    // locale component of this Config. If the locale is only country
+    // and language, it will look like en-rUS. If it has scripts and
+    // variants, it will be a modified bcp47 tag: b+en+Latn+US.
+    void appendDirLocale(String8& str) const;
+
     // Sets the values of language, region, script and variant to the
     // well formed BCP-47 locale contained in |in|. The input locale is
     // assumed to be valid and no validation is performed.
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index f935bb1..f0b07a6 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -36,6 +36,7 @@
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashSet;
+import java.security.spec.RSAKeyGenParameterSpec;
 
 import android.util.Log;
 import android.util.Base64;
@@ -713,6 +714,8 @@
         args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
         args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
         args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
+        args.addBlob(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
+                RSAKeyGenParameterSpec.F4.toByteArray());
 
         KeyCharacteristics outCharacteristics = new KeyCharacteristics();
         int result = mKeyStore.generateKey(name, args, 0, outCharacteristics);
@@ -750,6 +753,8 @@
         args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
         args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, new byte[] {0x01, 0x02, 0x03});
         args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
+        args.addBlob(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
+                RSAKeyGenParameterSpec.F4.toByteArray());
 
         KeyCharacteristics outCharacteristics = new KeyCharacteristics();
         int result = mKeyStore.generateKey(name, args, 0, outCharacteristics);
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index d5d583c..e247150 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -2550,6 +2550,58 @@
     return true;
 }
 
+void ResTable_config::appendDirLocale(String8& out) const {
+    if (!language[0]) {
+        return;
+    }
+
+    if (!localeScript[0] && !localeVariant[0]) {
+        // Legacy format.
+        if (out.size() > 0) {
+            out.append("-");
+        }
+
+        char buf[4];
+        size_t len = unpackLanguage(buf);
+        out.append(buf, len);
+
+        if (country[0]) {
+            out.append("-r");
+            len = unpackRegion(buf);
+            out.append(buf, len);
+        }
+        return;
+    }
+
+    // We are writing the modified bcp47 tag.
+    // It starts with 'b+' and uses '+' as a separator.
+
+    if (out.size() > 0) {
+        out.append("-");
+    }
+    out.append("b+");
+
+    char buf[4];
+    size_t len = unpackLanguage(buf);
+    out.append(buf, len);
+
+    if (localeScript[0]) {
+        out.append("+");
+        out.append(localeScript, sizeof(localeScript));
+    }
+
+    if (country[0]) {
+        out.append("+");
+        len = unpackRegion(buf);
+        out.append(buf, len);
+    }
+
+    if (localeVariant[0]) {
+        out.append("+");
+        out.append(localeVariant, sizeof(localeVariant));
+    }
+}
+
 void ResTable_config::getBcp47Locale(char str[RESTABLE_MAX_LOCALE_LEN]) const {
     memset(str, 0, RESTABLE_MAX_LOCALE_LEN);
 
@@ -2650,12 +2702,7 @@
         res.appendFormat("mnc%d", dtohs(mnc));
     }
 
-    char localeStr[RESTABLE_MAX_LOCALE_LEN];
-    getBcp47Locale(localeStr);
-    if (strlen(localeStr) > 0) {
-        if (res.size() > 0) res.append("-");
-        res.append(localeStr);
-    }
+    appendDirLocale(res);
 
     if ((screenLayout&MASK_LAYOUTDIR) != 0) {
         if (res.size() > 0) res.append("-");
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index ea4216c..0091790 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -418,6 +418,7 @@
 }
 
 void RenderProxy::dumpGraphicsMemory(int fd) {
+    if (!RenderThread::hasInstance()) return;
     SETUP_TASK(dumpGraphicsMemory);
     args->fd = fd;
     args->thread = &RenderThread::getInstance();
diff --git a/libs/hwui/thread/Signal.h b/libs/hwui/thread/Signal.h
index dcf5449..d4cfeeb 100644
--- a/libs/hwui/thread/Signal.h
+++ b/libs/hwui/thread/Signal.h
@@ -30,8 +30,10 @@
     ~Signal() { }
 
     void signal() {
-        Mutex::Autolock l(mLock);
-        mSignaled = true;
+        {
+            Mutex::Autolock l(mLock);
+            mSignaled = true;
+        }
         mCondition.signal(mType);
     }
 
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index c69b2fd..f0ed0bb 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -109,8 +109,11 @@
         return false;
     }
 
-    Mutex::Autolock l(mLock);
-    ssize_t index = mTasks.add(task);
+    ssize_t index;
+    {
+        Mutex::Autolock l(mLock);
+        index = mTasks.add(task);
+    }
     mSignal.signal();
 
     return index >= 0;
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 53ab264..9d07492 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -115,14 +115,49 @@
     /**
      * Get the timestamp associated with this frame.
      * <p>
-     * The timestamp is measured in nanoseconds, and is monotonically
-     * increasing. However, the zero point and whether the timestamp can be
-     * compared against other sources of time or images depend on the source of
-     * this image.
+     * The timestamp is measured in nanoseconds, and is normally monotonically
+     * increasing. However, the behavior of the timestamp depends on the source
+     * of this image. See {@link android.hardware.Camera Camera},
+     * {@link android.hardware.camera2.CameraDevice CameraDevice}, {@link MediaPlayer} and
+     * {@link MediaCodec} for more details.
      * </p>
      */
     public abstract long getTimestamp();
 
+    /**
+     * Set the timestamp associated with this frame.
+     * <p>
+     * The timestamp is measured in nanoseconds, and is normally monotonically
+     * increasing. However, However, the behavior of the timestamp depends on
+     * the destination of this image. See {@link android.hardware.Camera Camera}
+     * , {@link android.hardware.camera2.CameraDevice CameraDevice},
+     * {@link MediaPlayer} and {@link MediaCodec} for more details.
+     * </p>
+     * <p>
+     * For images dequeued from {@link ImageWriter} via
+     * {@link ImageWriter#dequeueInputImage()}, it's up to the application to
+     * set the timestamps correctly before sending them back to the
+     * {@link ImageWriter}, or the timestamp will be generated automatically when
+     * {@link ImageWriter#queueInputImage queueInputImage()} is called.
+     * </p>
+     *
+     * @param timestamp The timestamp to be set for this image.
+     */
+    public void setTimestamp(long timestamp) {
+        return;
+    }
+
+    /**
+     * <p>Check if the image is opaque.</p>
+     *
+     * <p>The pixel data of opaque images are not accessible to the application,
+     * and therefore {@link #getPlanes} will return an empty array for an opaque image.
+     * </p>
+     */
+    public boolean isOpaque() {
+        return false;
+    }
+
     private Rect mCropRect;
 
     /**
@@ -155,7 +190,10 @@
 
     /**
      * Get the array of pixel planes for this Image. The number of planes is
-     * determined by the format of the Image.
+     * determined by the format of the Image. The application will get an
+     * empty array if the image is opaque because the opaque image pixel data
+     * is not directly accessible. The application can check if an image is
+     * opaque by calling {@link Image#isOpaque}.
      */
     public abstract Plane[] getPlanes();
 
@@ -164,14 +202,54 @@
      * <p>
      * After calling this method, calling any methods on this {@code Image} will
      * result in an {@link IllegalStateException}, and attempting to read from
-     * {@link ByteBuffer ByteBuffers} returned by an earlier
-     * {@link Plane#getBuffer} call will have undefined behavior.
+     * or write to {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Plane#getBuffer} call will have undefined behavior. If the image
+     * was obtained from {@link ImageWriter} via
+     * {@link ImageWriter#dequeueInputImage()}, after calling this method, any
+     * image data filled by the application will be lost and the image will be
+     * returned to {@link ImageWriter} for reuse. Images given to
+     * {@link ImageWriter#queueInputImage queueInputImage()} are automatically
+     * closed.
      * </p>
      */
     @Override
     public abstract void close();
 
     /**
+     * <p>
+     * Check if the image can be attached to a new owner (e.g. {@link ImageWriter}).
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @return true if the image is attachable to a new owner, false if the image is still attached
+     *         to its current owner, or the image is a stand-alone image and is not attachable to
+     *         a new owner.
+     */
+    boolean isAttachable() {
+        return false;
+    }
+
+    /**
+     * <p>
+     * Get the owner of the {@link Image}.
+     * </p>
+     * <p>
+     * The owner of an {@link Image} could be {@link ImageReader}, {@link ImageWriter},
+     * {@link MediaCodec} etc. This method returns the owner that produces this image, or null
+     * if the image is stand-alone image or the owner is unknown.
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @return The owner of the Image.
+     */
+    Object getOwner() {
+        return null;
+    }
+    /**
      * <p>A single color plane of image data.</p>
      *
      * <p>The number and meaning of the planes in an Image are determined by the
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 18ffe12..b2f7a20 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -27,6 +27,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * <p>The ImageReader class allows direct application access to image data
@@ -34,7 +35,7 @@
  *
  * <p>Several Android media API classes accept Surface objects as targets to
  * render to, including {@link MediaPlayer}, {@link MediaCodec},
- * {@link android.hardware.camera2.CameraDevice}, and
+ * {@link android.hardware.camera2.CameraDevice}, {@link ImageWriter} and
  * {@link android.renderscript.Allocation RenderScript Allocations}. The image
  * sizes and formats that can be used with each source vary, and should be
  * checked in the documentation for the specific API.</p>
@@ -97,10 +98,60 @@
      * @see Image
      */
     public static ImageReader newInstance(int width, int height, int format, int maxImages) {
+        if (format == PixelFormat.OPAQUE) {
+            throw new IllegalArgumentException("To obtain an opaque ImageReader, please use"
+                    + " newOpaqueInstance rather than newInstance");
+        }
         return new ImageReader(width, height, format, maxImages);
     }
 
     /**
+     * <p>
+     * Create a new opaque reader for images of the desired size.
+     * </p>
+     * <p>
+     * An opaque {@link ImageReader} produces images that are not directly
+     * accessible by the application. The application can still acquire images
+     * from an opaque image reader, and send them to the
+     * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via
+     * {@link ImageWriter} interface. However, the {@link Image#getPlanes()
+     * getPlanes()} will return an empty array for opaque images. The
+     * application can check if an existing reader is an opaque reader by
+     * calling {@link #isOpaque()}.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be acquired from the
+     * {@code ImageReader} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary.
+     * </p>
+     * <p>
+     * The valid sizes and formats depend on the source of the image data.
+     * </p>
+     * <p>
+     * Opaque ImageReaders are more efficient to use when application access to
+     * image data is not necessary, comparing to ImageReaders using a non-opaque
+     * format such as {@link ImageFormat#YUV_420_888 YUV_420_888}.
+     * </p>
+     *
+     * @param width The default width in pixels of the Images that this reader
+     *            will produce.
+     * @param height The default height in pixels of the Images that this reader
+     *            will produce.
+     * @param maxImages The maximum number of images the user will want to
+     *            access simultaneously. This should be as small as possible to
+     *            limit memory use. Once maxImages Images are obtained by the
+     *            user, one of them has to be released before a new Image will
+     *            become available for access through
+     *            {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
+     *            Must be greater than 0.
+     * @see Image
+     */
+    public static ImageReader newOpaqueInstance(int width, int height, int maxImages) {
+        return new ImageReader(width, height, PixelFormat.OPAQUE, maxImages);
+    }
+
+    /**
      * @hide
      */
     protected ImageReader(int width, int height, int format, int maxImages) {
@@ -197,6 +248,23 @@
     }
 
     /**
+     * <p>
+     * Check if the {@link ImageReader} is an opaque reader.
+     * </p>
+     * <p>
+     * An opaque image reader produces opaque images, see {@link Image#isOpaque}
+     * for more details.
+     * </p>
+     *
+     * @return true if the ImageReader is opaque.
+     * @see Image#isOpaque
+     * @see ImageReader#newOpaqueInstance
+     */
+    public boolean isOpaque() {
+        return mFormat == PixelFormat.OPAQUE;
+    }
+
+    /**
      * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
      * {@code ImageReader}.</p>
      *
@@ -457,6 +525,58 @@
     }
 
     /**
+     * <p>
+     * Remove the ownership of this image from the ImageReader.
+     * </p>
+     * <p>
+     * After this call, the ImageReader no longer owns this image, and the image
+     * ownership can be transfered to another entity like {@link ImageWriter}
+     * via {@link ImageWriter#queueInputImage}. It's up to the new owner to
+     * release the resources held by this image. For example, if the ownership
+     * of this image is transfered to an {@link ImageWriter}, the image will be
+     * freed by the ImageWriter after the image data consumption is done.
+     * </p>
+     * <p>
+     * This method can be used to achieve zero buffer copy for use cases like
+     * {@link android.hardware.camera2.CameraDevice Camera2 API} OPAQUE and YUV
+     * reprocessing, where the application can select an output image from
+     * {@link ImageReader} and transfer this image directly to
+     * {@link ImageWriter}, where this image can be consumed by camera directly.
+     * For OPAQUE reprocessing, this is the only way to send input buffers to
+     * the {@link android.hardware.camera2.CameraDevice camera} for
+     * reprocessing.
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @param image The image to be detached from this ImageReader.
+     * @throws IllegalStateException If the ImageReader or image have been
+     *             closed, or the has been detached, or has not yet been
+     *             acquired.
+     */
+     void detachImage(Image image) {
+       if (image == null) {
+           throw new IllegalArgumentException("input image must not be null");
+       }
+       if (!isImageOwnedbyMe(image)) {
+           throw new IllegalArgumentException("Trying to detach an image that is not owned by"
+                   + " this ImageReader");
+       }
+
+        SurfaceImage si = (SurfaceImage) image;
+        if (!si.isImageValid()) {
+            throw new IllegalStateException("Image is no longer valid");
+        }
+        if (si.isAttachable()) {
+            throw new IllegalStateException("Image was already detached from this ImageReader");
+        }
+
+        nativeDetachImage(image);
+        si.setDetached(true);
+   }
+
+    /**
      * Only a subset of the formats defined in
      * {@link android.graphics.ImageFormat ImageFormat} and
      * {@link android.graphics.PixelFormat PixelFormat} are supported by
@@ -487,12 +607,22 @@
             case ImageFormat.DEPTH16:
             case ImageFormat.DEPTH_POINT_CLOUD:
                 return 1;
+            case PixelFormat.OPAQUE:
+                return 0;
             default:
                 throw new UnsupportedOperationException(
                         String.format("Invalid format specified %d", mFormat));
         }
     }
 
+    private boolean isImageOwnedbyMe(Image image) {
+        if (!(image instanceof SurfaceImage)) {
+            return false;
+        }
+        SurfaceImage si = (SurfaceImage) image;
+        return si.getReader() == this;
+    }
+
     /**
      * Called from Native code when an Event happens.
      *
@@ -561,7 +691,11 @@
         @Override
         public void close() {
             if (mIsImageValid) {
-                ImageReader.this.releaseImage(this);
+                if (!mIsDetached.get()) {
+                    // For detached images, the new owner is responsible for
+                    // releasing the resources
+                    ImageReader.this.releaseImage(this);
+                }
             }
         }
 
@@ -614,6 +748,15 @@
         }
 
         @Override
+        public void setTimestamp(long timestampNs) {
+            if (mIsImageValid) {
+                mTimestamp = timestampNs;
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
         public Plane[] getPlanes() {
             if (mIsImageValid) {
                 // Shallow copy is fine.
@@ -624,6 +767,11 @@
         }
 
         @Override
+        public boolean isOpaque() {
+            return mFormat == PixelFormat.OPAQUE;
+        }
+
+        @Override
         protected final void finalize() throws Throwable {
             try {
                 close();
@@ -632,6 +780,20 @@
             }
         }
 
+        @Override
+        boolean isAttachable() {
+            return mIsDetached.get();
+        }
+
+        @Override
+        ImageReader getOwner() {
+            return ImageReader.this;
+        }
+
+        private void setDetached(boolean detached) {
+            mIsDetached.getAndSet(detached);
+        }
+
         private void setImageValid(boolean isValid) {
             mIsImageValid = isValid;
         }
@@ -734,6 +896,8 @@
         private boolean mIsImageValid;
         private int mHeight = -1;
         private int mWidth = -1;
+        // If this image is detached from the ImageReader.
+        private AtomicBoolean mIsDetached = new AtomicBoolean(false);
 
         private synchronized native ByteBuffer nativeImageGetBuffer(int idx, int readerFormat);
         private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat);
@@ -746,6 +910,7 @@
     private synchronized native void nativeClose();
     private synchronized native void nativeReleaseImage(Image i);
     private synchronized native Surface nativeGetSurface();
+    private synchronized native void nativeDetachImage(Image i);
 
     /**
      * @return A return code {@code ACQUIRE_*}
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
new file mode 100644
index 0000000..89313bf3
--- /dev/null
+++ b/media/java/android/media/ImageUtils.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.graphics.ImageFormat;
+import android.graphics.PixelFormat;
+import android.media.Image.Plane;
+import android.util.Size;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Package private utility class for hosting commonly used Image related methods.
+ */
+class ImageUtils {
+
+    /**
+     * Only a subset of the formats defined in
+     * {@link android.graphics.ImageFormat ImageFormat} and
+     * {@link android.graphics.PixelFormat PixelFormat} are supported by
+     * ImageReader. When reading RGB data from a surface, the formats defined in
+     * {@link android.graphics.PixelFormat PixelFormat} can be used; when
+     * reading YUV, JPEG or raw sensor data (for example, from the camera or video
+     * decoder), formats from {@link android.graphics.ImageFormat ImageFormat}
+     * are used.
+     */
+    public static int getNumPlanesForFormat(int format) {
+        switch (format) {
+            case ImageFormat.YV12:
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+                return 3;
+            case ImageFormat.NV16:
+                return 2;
+            case PixelFormat.RGB_565:
+            case PixelFormat.RGBA_8888:
+            case PixelFormat.RGBX_8888:
+            case PixelFormat.RGB_888:
+            case ImageFormat.JPEG:
+            case ImageFormat.YUY2:
+            case ImageFormat.Y8:
+            case ImageFormat.Y16:
+            case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW10:
+                return 1;
+            case PixelFormat.OPAQUE:
+                return 0;
+            default:
+                throw new UnsupportedOperationException(
+                        String.format("Invalid format specified %d", format));
+        }
+    }
+
+    /**
+     * <p>
+     * Copy source image data to destination Image.
+     * </p>
+     * <p>
+     * Only support the copy between two non-opaque images with same properties
+     * (format, size, etc.). The data from the source image will be copied to
+     * the byteBuffers from the destination Image starting from position zero,
+     * and the destination image will be rewound to zero after copy is done.
+     * </p>
+     *
+     * @param src The source image to be copied from.
+     * @param dst The destination image to be copied to.
+     * @throws IllegalArgumentException If the source and destination images
+     *             have different format, or one of the images is not copyable.
+     */
+    public static void imageCopy(Image src, Image dst) {
+        if (src == null || dst == null) {
+            throw new IllegalArgumentException("Images should be non-null");
+        }
+        if (src.getFormat() != dst.getFormat()) {
+            throw new IllegalArgumentException("Src and dst images should have the same format");
+        }
+        if (src.isOpaque() || dst.isOpaque()) {
+            throw new IllegalArgumentException("Opaque image is not copyable");
+        }
+        if (!(dst.getOwner() instanceof ImageWriter)) {
+            throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
+                    + " the images from ImageWriter are writable");
+        }
+        Size srcSize = new Size(src.getWidth(), src.getHeight());
+        Size dstSize = new Size(dst.getWidth(), dst.getHeight());
+        if (!srcSize.equals(dstSize)) {
+            throw new IllegalArgumentException("source image size " + srcSize + " is different"
+                    + " with " + "destination image size " + dstSize);
+        }
+
+        Plane[] srcPlanes = src.getPlanes();
+        Plane[] dstPlanes = dst.getPlanes();
+        ByteBuffer srcBuffer = null;
+        ByteBuffer dstBuffer = null;
+        for (int i = 0; i < srcPlanes.length; i++) {
+            srcBuffer = srcPlanes[i].getBuffer();
+            int srcPos = srcBuffer.position();
+            srcBuffer.rewind();
+            dstBuffer = dstPlanes[i].getBuffer();
+            dstBuffer.rewind();
+            dstBuffer.put(srcBuffer);
+            srcBuffer.position(srcPos);
+            dstBuffer.rewind();
+        }
+    }
+}
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
new file mode 100644
index 0000000..20389a39
--- /dev/null
+++ b/media/java/android/media/ImageWriter.java
@@ -0,0 +1,798 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.Surface;
+
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.NioUtils;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * <p>
+ * The ImageWriter class allows an application to produce Image data into a
+ * {@link android.view.Surface}, and have it be consumed by another component like
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.
+ * </p>
+ * <p>
+ * Several Android API classes can provide input {@link android.view.Surface
+ * Surface} objects for ImageWriter to produce data into, including
+ * {@link MediaCodec MediaCodec} (encoder),
+ * {@link android.hardware.camera2.CameraDevice CameraDevice} (reprocessing
+ * input), {@link ImageReader}, etc.
+ * </p>
+ * <p>
+ * The input Image data is encapsulated in {@link Image} objects. To produce
+ * Image data into a destination {@link android.view.Surface Surface}, the
+ * application can get an input Image via {@link #dequeueInputImage} then write
+ * Image data into it. Multiple such {@link Image} objects can be dequeued at
+ * the same time and queued back in any order, up to the number specified by the
+ * {@code maxImages} constructor parameter.
+ * </p>
+ * <p>
+ * If the application already has an Image from {@link ImageReader}, the
+ * application can directly queue this Image into ImageWriter (via
+ * {@link #queueInputImage}), potentially with zero buffer copies. For the opaque
+ * Images produced by an opaque ImageReader (created by
+ * {@link ImageReader#newOpaqueInstance}), this is the only way to send Image
+ * data to ImageWriter, as the Image data aren't accessible by the application.
+ * </p>
+ * Once new input Images are queued into an ImageWriter, it's up to the downstream
+ * components (e.g. {@link ImageReader} or
+ * {@link android.hardware.camera2.CameraDevice}) to consume the Images. If the
+ * downstream components cannot consume the Images at least as fast as the
+ * ImageWriter production rate, the {@link #dequeueInputImage} call will eventually
+ * block and the application will have to drop input frames. </p>
+ */
+public class ImageWriter implements AutoCloseable {
+    private final Object mListenerLock = new Object();
+    private ImageListener mListener;
+    private ListenerHandler mListenerHandler;
+    private long mNativeContext;
+
+    // Field below is used by native code, do not access or modify.
+    private int mWriterFormat;
+
+    private final int mMaxImages;
+    // Keep track of the currently attached Image; or an attached Image that is
+    // released will be removed from this list.
+    private List<Image> mAttachedImages = new ArrayList<Image>();
+    private List<Image> mDequeuedImages = new ArrayList<Image>();
+
+    /**
+     * <p>
+     * Create a new ImageWriter.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be dequeued from the
+     * {@code ImageWriter} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary.
+     * </p>
+     * <p>
+     * The input Image size and format depend on the Surface that is provided by
+     * the downstream consumer end-point.
+     * </p>
+     *
+     * @param surface The destination Surface this writer produces Image data
+     *            into.
+     * @param maxImages The maximum number of Images the user will want to
+     *            access simultaneously for producing Image data. This should be
+     *            as small as possible to limit memory use. Once maxImages
+     *            Images are dequeued by the user, one of them has to be queued
+     *            back before a new Image can be dequeued for access via
+     *            {@link #dequeueInputImage()}.
+     * @return a new ImageWriter instance.
+     */
+    public static ImageWriter newInstance(Surface surface, int maxImages) {
+        return new ImageWriter(surface, maxImages);
+    }
+
+    /**
+     * @hide
+     */
+    protected ImageWriter(Surface surface, int maxImages) {
+        if (surface == null || maxImages < 1) {
+            throw new IllegalArgumentException("Illegal input argument: surface " + surface
+                    + ", maxImages: " + maxImages);
+        }
+
+        mMaxImages = maxImages;
+        // Note that the underlying BufferQueue is working in synchronous mode
+        // to avoid dropping any buffers.
+        mNativeContext = nativeInit(new WeakReference<ImageWriter>(this), surface, maxImages);
+    }
+
+    /**
+     * <p>
+     * Maximum number of Images that can be dequeued from the ImageWriter
+     * simultaneously (for example, with {@link #dequeueInputImage()}).
+     * </p>
+     * <p>
+     * An Image is considered dequeued after it's returned by
+     * {@link #dequeueInputImage()} from ImageWriter, and until the Image is
+     * sent back to ImageWriter via {@link #queueInputImage}, or
+     * {@link Image#close()}.
+     * </p>
+     * <p>
+     * Attempting to dequeue more than {@code maxImages} concurrently will
+     * result in the {@link #dequeueInputImage()} function throwing an
+     * {@link IllegalStateException}.
+     * </p>
+     *
+     * @return Maximum number of Images that can be dequeued from this
+     *         ImageWriter.
+     * @see #dequeueInputImage
+     * @see #queueInputImage
+     * @see Image#close
+     */
+    public int getMaxImages() {
+        return mMaxImages;
+    }
+
+    /**
+     * <p>
+     * Dequeue the next available input Image for the application to produce
+     * data into.
+     * </p>
+     * <p>
+     * This method requests a new input Image from ImageWriter. The application
+     * owns this Image after this call. Once the application fills the Image
+     * data, it is expected to return this Image back to ImageWriter for
+     * downstream consumer components (e.g.
+     * {@link android.hardware.camera2.CameraDevice}) to consume. The Image can
+     * be returned to ImageWriter via {@link #queueInputImage} or
+     * {@link Image#close()}.
+     * </p>
+     * <p>
+     * This call will block if all available input images have been filled by
+     * the application and the downstream consumer has not yet consumed any.
+     * When an Image is consumed by the downstream consumer, an
+     * {@link ImageListener#onInputImageReleased} callback will be fired, which
+     * indicates that there is one input Image available. It is recommended to
+     * dequeue next Image only after this callback is fired, in the steady state.
+     * </p>
+     *
+     * @return The next available input Image from this ImageWriter.
+     * @throws IllegalStateException if {@code maxImages} Images are currently
+     *             dequeued.
+     * @see #queueInputImage
+     * @see Image#close
+     */
+    public Image dequeueInputImage() {
+        if (mDequeuedImages.size() >= mMaxImages) {
+            throw new IllegalStateException("Already dequeued max number of Images " + mMaxImages);
+        }
+        WriterSurfaceImage newImage = new WriterSurfaceImage(this);
+        nativeDequeueInputImage(mNativeContext, newImage);
+        mDequeuedImages.add(newImage);
+        newImage.setImageValid(true);
+        return newImage;
+    }
+
+    /**
+     * <p>
+     * Queue an input {@link Image} back to ImageWriter for the downstream
+     * consumer to access.
+     * </p>
+     * <p>
+     * The input {@link Image} could be from ImageReader (acquired via
+     * {@link ImageReader#acquireNextImage} or
+     * {@link ImageReader#acquireLatestImage}), or from this ImageWriter
+     * (acquired via {@link #dequeueInputImage}). In the former case, the Image
+     * data will be moved to this ImageWriter. Note that the Image properties
+     * (size, format, strides, etc.) must be the same as the properties of the
+     * images dequeued from this ImageWriter, or this method will throw an
+     * {@link IllegalArgumentException}. In the latter case, the application has
+     * filled the input image with data. This method then passes the filled
+     * buffer to the downstream consumer. In both cases, it's up to the caller
+     * to ensure that the Image timestamp (in nanoseconds) is correctly set, as
+     * the downstream component may want to use it to indicate the Image data
+     * capture time.
+     * </p>
+     * <p>
+     * Passing in a non-opaque Image may result in a memory copy, which also
+     * requires a free input Image from this ImageWriter as the destination. In
+     * this case, this call will block, as {@link #dequeueInputImage} does, if
+     * there are no free Images available. To be safe, the application should ensure
+     * that there is at least one free Image available in this ImageWriter before calling
+     * this method.
+     * </p>
+     * <p>
+     * After this call, the input Image is no longer valid for further access,
+     * as if the Image is {@link Image#close closed}. Attempting to access the
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will result in an
+     * {@link IllegalStateException}.
+     * </p>
+     *
+     * @param image The Image to be queued back to ImageWriter for future
+     *            consumption.
+     * @see #dequeueInputImage()
+     */
+    public void queueInputImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+        boolean ownedByMe = isImageOwnedByMe(image);
+        if (ownedByMe && !(((WriterSurfaceImage) image).isImageValid())) {
+            throw new IllegalStateException("Image from ImageWriter is invalid");
+        }
+
+        // For images from other components, need to detach first, then attach.
+        if (!ownedByMe) {
+            if (!(image.getOwner() instanceof ImageReader)) {
+                throw new IllegalArgumentException("Only images from ImageReader can be queued to"
+                        + " ImageWriter, other image source is not supported yet!");
+            }
+
+            ImageReader prevOwner = (ImageReader) image.getOwner();
+            // Only do the image attach for opaque images for now. Do the image
+            // copy for other formats. TODO: use attach for other formats to
+            // improve the performance, and fall back to copy when attach/detach fails.
+            if (image.isOpaque()) {
+                prevOwner.detachImage(image);
+                attachInputImage(image);
+            } else {
+                Image inputImage = dequeueInputImage();
+                inputImage.setTimestamp(image.getTimestamp());
+                inputImage.setCropRect(image.getCropRect());
+                ImageUtils.imageCopy(image, inputImage);
+                image.close();
+                image = inputImage;
+                ownedByMe = true;
+            }
+        }
+
+        Rect crop = image.getCropRect();
+        nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), crop.left, crop.top,
+                crop.right, crop.bottom);
+
+        /**
+         * Only remove and cleanup the Images that are owned by this
+         * ImageWriter. Images detached from other owners are only
+         * temporarily owned by this ImageWriter and will be detached immediately
+         * after they are released by downstream consumers, so there is no need to
+         * keep track of them in mDequeuedImages.
+         */
+        if (ownedByMe) {
+            mDequeuedImages.remove(image);
+            WriterSurfaceImage wi = (WriterSurfaceImage) image;
+            wi.clearSurfacePlanes();
+            wi.setImageValid(false);
+        } else {
+            // This clears the native reference held by the original owner. When
+            // this Image is detached later by this ImageWriter, the native
+            // memory won't be leaked.
+            image.close();
+        }
+    }
+
+    /**
+     * ImageWriter callback interface, used to to asynchronously notify the
+     * application of various ImageWriter events.
+     */
+    public interface ImageListener {
+        /**
+         * <p>
+         * Callback that is called when an input Image is released back to
+         * ImageWriter after the data consumption.
+         * </p>
+         * <p>
+         * The client can use this callback to indicate either an input Image is
+         * available to fill data into, or the input Image is returned and freed
+         * if it was attached from other components (e.g. an
+         * {@link ImageReader}). For the latter case, the ownership of the Image
+         * will be automatically removed by ImageWriter right before this
+         * callback is fired.
+         * </p>
+         *
+         * @param writer the ImageWriter the callback is associated with.
+         * @see ImageWriter
+         * @see Image
+         */
+        // TODO: the semantics is confusion, does't tell which buffer is
+        // released if an application is doing queueInputImage with a mix of
+        // buffers from dequeueInputImage and from an ImageReader. see b/19872821
+        void onInputImageReleased(ImageWriter writer);
+    }
+
+    /**
+     * Register a listener to be invoked when an input Image is returned to
+     * the ImageWriter.
+     *
+     * @param listener The listener that will be run.
+     * @param handler The handler on which the listener should be invoked, or
+     *            null if the listener should be invoked on the calling thread's
+     *            looper.
+     * @throws IllegalArgumentException If no handler specified and the calling
+     *             thread has no looper.
+     */
+    public void setImageListener(ImageListener listener, Handler handler) {
+        synchronized (mListenerLock) {
+            if (listener != null) {
+                Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
+                if (looper == null) {
+                    throw new IllegalArgumentException(
+                            "handler is null but the current thread is not a looper");
+                }
+                if (mListenerHandler == null || mListenerHandler.getLooper() != looper) {
+                    mListenerHandler = new ListenerHandler(looper);
+                }
+                mListener = listener;
+            } else {
+                mListener = null;
+                mListenerHandler = null;
+            }
+        }
+    }
+
+    /**
+     * Free up all the resources associated with this ImageWriter.
+     * <p>
+     * After calling this method, this ImageWriter cannot be used. Calling any
+     * methods on this ImageWriter and Images previously provided by
+     * {@link #dequeueInputImage()} will result in an
+     * {@link IllegalStateException}, and attempting to write into
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will have undefined
+     * behavior.
+     * </p>
+     */
+    @Override
+    public void close() {
+        setImageListener(null, null);
+        for (Image image : mDequeuedImages) {
+            image.close();
+        }
+        mDequeuedImages.clear();
+        nativeClose(mNativeContext);
+        mNativeContext = 0;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Get the ImageWriter format.
+     * <p>
+     * This format may be different than the Image format returned by
+     * {@link Image#getFormat()}
+     * </p>
+     *
+     * @return The ImageWriter format.
+     */
+    int getFormat() {
+        return mWriterFormat;
+    }
+
+
+    /**
+     * <p>
+     * Attach input Image to this ImageWriter.
+     * </p>
+     * <p>
+     * When an Image is from an opaque source (e.g. an opaque ImageReader created
+     * by {@link ImageReader#newOpaqueInstance}), or the source Image is so large
+     * that copying its data is too expensive, this method can be used to
+     * migrate the source Image into ImageWriter without a data copy. The source
+     * Image must be detached from its previous owner already, or this call will
+     * throw an {@link IllegalStateException}.
+     * </p>
+     * <p>
+     * After this call, the ImageWriter takes ownership of this Image.
+     * This ownership will be automatically removed from this writer after the
+     * consumer releases this Image, that is, after
+     * {@link ImageListener#onInputImageReleased}. The caller is
+     * responsible for closing this Image through {@link Image#close()} to free up
+     * the resources held by this Image.
+     * </p>
+     *
+     * @param image The source Image to be attached and queued into this
+     *            ImageWriter for downstream consumer to use.
+     * @throws IllegalStateException if the Image is not detached from its
+     *             previous owner, or the Image is already attached to this
+     *             ImageWriter, or the source Image is invalid.
+     */
+    private void attachInputImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+        if (isImageOwnedByMe(image)) {
+            throw new IllegalArgumentException(
+                    "Can not attach an image that is owned ImageWriter already");
+        }
+        /**
+         * Throw ISE if the image is not attachable, which means that it is
+         * either owned by other entity now, or completely non-attachable (some
+         * stand-alone images are not backed by native gralloc buffer, thus not
+         * attachable).
+         */
+        if (!image.isAttachable()) {
+            throw new IllegalStateException("Image was not detached from last owner, or image "
+                    + " is not detachable");
+        }
+        if (mAttachedImages.contains(image)) {
+            throw new IllegalStateException("Image was already attached to ImageWritter");
+        }
+
+        // TODO: what if attach failed, throw RTE or detach a slot then attach?
+        // need do some cleanup to make sure no orphaned
+        // buffer caused leak.
+        nativeAttachImage(mNativeContext, image);
+        mAttachedImages.add(image);
+    }
+
+    /**
+     * This custom handler runs asynchronously so callbacks don't get queued
+     * behind UI messages.
+     */
+    private final class ListenerHandler extends Handler {
+        public ListenerHandler(Looper looper) {
+            super(looper, null, true /* async */);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            ImageListener listener;
+            synchronized (mListenerLock) {
+                listener = mListener;
+            }
+            // TODO: detach Image from ImageWriter and remove the Image from
+            // mAttachedImage list.
+            if (listener != null) {
+                listener.onInputImageReleased(ImageWriter.this);
+            }
+        }
+    }
+
+    /**
+     * Called from Native code when an Event happens. This may be called from an
+     * arbitrary Binder thread, so access to the ImageWriter must be
+     * synchronized appropriately.
+     */
+    private static void postEventFromNative(Object selfRef) {
+        @SuppressWarnings("unchecked")
+        WeakReference<ImageWriter> weakSelf = (WeakReference<ImageWriter>) selfRef;
+        final ImageWriter iw = weakSelf.get();
+        if (iw == null) {
+            return;
+        }
+
+        final Handler handler;
+        synchronized (iw.mListenerLock) {
+            handler = iw.mListenerHandler;
+        }
+        if (handler != null) {
+            handler.sendEmptyMessage(0);
+        }
+    }
+
+    /**
+     * <p>
+     * Abort the Images that were dequeued from this ImageWriter, and return
+     * them to this writer for reuse.
+     * </p>
+     * <p>
+     * This method is used for the cases where the application dequeued the
+     * Image, may have filled the data, but does not want the downstream
+     * component to consume it. The Image will be returned to this ImageWriter
+     * for reuse after this call, and the ImageWriter will immediately have an
+     * Image available to be dequeued. This aborted Image will be invisible to
+     * the downstream consumer, as if nothing happened.
+     * </p>
+     *
+     * @param image The Image to be aborted.
+     * @see #dequeueInputImage()
+     * @see Image#close()
+     */
+    private void abortImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+
+        if (!mDequeuedImages.contains(image)) {
+            throw new IllegalStateException("It is illegal to abort some image that is not"
+                    + " dequeued yet");
+        }
+
+        WriterSurfaceImage wi = (WriterSurfaceImage) image;
+
+        if (!wi.isImageValid()) {
+            throw new IllegalStateException("Image is invalid");
+        }
+
+        /**
+         * We only need abort Images that are owned and dequeued by ImageWriter.
+         * For attached Images, no need to abort, as there are only two cases:
+         * attached + queued successfully, and attach failed. Neither of the
+         * cases need abort.
+         */
+        cancelImage(mNativeContext,image);
+        mDequeuedImages.remove(image);
+        wi.clearSurfacePlanes();
+        wi.setImageValid(false);
+    }
+
+    private boolean isImageOwnedByMe(Image image) {
+        if (!(image instanceof WriterSurfaceImage)) {
+            return false;
+        }
+        WriterSurfaceImage wi = (WriterSurfaceImage) image;
+        if (wi.getOwner() != this) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static class WriterSurfaceImage extends android.media.Image {
+        private ImageWriter mOwner;
+        private AtomicBoolean mIsImageValid = new AtomicBoolean(false);
+        // This field is used by native code, do not access or modify.
+        private long mNativeBuffer;
+        private int mNativeFenceFd = -1;
+        private SurfacePlane[] mPlanes;
+        private int mHeight = -1;
+        private int mWidth = -1;
+        private int mFormat = -1;
+        // When this default timestamp is used, timestamp for the input Image
+        // will be generated automatically when queueInputBuffer is called.
+        private final long DEFAULT_TIMESTAMP = Long.MIN_VALUE;
+        private long mTimestamp = DEFAULT_TIMESTAMP;
+
+        public WriterSurfaceImage(ImageWriter writer) {
+            mOwner = writer;
+        }
+
+        @Override
+        public int getFormat() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+            if (mFormat == -1) {
+                mFormat = nativeGetFormat();
+            }
+            return mFormat;
+        }
+
+        @Override
+        public int getWidth() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            if (mWidth == -1) {
+                mWidth = nativeGetWidth();
+            }
+
+            return mWidth;
+        }
+
+        @Override
+        public int getHeight() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            if (mHeight == -1) {
+                mHeight = nativeGetHeight();
+            }
+
+            return mHeight;
+        }
+
+        @Override
+        public long getTimestamp() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            return mTimestamp;
+        }
+
+        @Override
+        public void setTimestamp(long timestamp) {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            mTimestamp = timestamp;
+        }
+
+        @Override
+        public boolean isOpaque() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            return getFormat() == PixelFormat.OPAQUE;
+        }
+
+        @Override
+        public Plane[] getPlanes() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+
+            if (mPlanes == null) {
+                int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
+                mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat());
+            }
+
+            return mPlanes.clone();
+        }
+
+        @Override
+        boolean isAttachable() {
+            if (!mIsImageValid.get()) {
+                throw new IllegalStateException("Image is already released");
+            }
+            // Don't allow Image to be detached from ImageWriter for now, as no
+            // detach API is exposed.
+            return false;
+        }
+
+        @Override
+        ImageWriter getOwner() {
+            return mOwner;
+        }
+
+        @Override
+        public void close() {
+            if (mIsImageValid.get()) {
+                getOwner().abortImage(this);
+            }
+        }
+
+        @Override
+        protected final void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+
+        private boolean isImageValid() {
+            return mIsImageValid.get();
+        }
+
+        private void setImageValid(boolean isValid) {
+            mIsImageValid.getAndSet(isValid);
+        }
+
+        private void clearSurfacePlanes() {
+            if (mIsImageValid.get()) {
+                for (int i = 0; i < mPlanes.length; i++) {
+                    if (mPlanes[i] != null) {
+                        mPlanes[i].clearBuffer();
+                        mPlanes[i] = null;
+                    }
+                }
+            }
+        }
+
+        private class SurfacePlane extends android.media.Image.Plane {
+            private ByteBuffer mBuffer;
+            final private int mPixelStride;
+            final private int mRowStride;
+
+            // SurfacePlane instance is created by native code when a new
+            // SurfaceImage is created
+            private SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
+                mRowStride = rowStride;
+                mPixelStride = pixelStride;
+                mBuffer = buffer;
+                /**
+                 * Set the byteBuffer order according to host endianness (native
+                 * order), otherwise, the byteBuffer order defaults to
+                 * ByteOrder.BIG_ENDIAN.
+                 */
+                mBuffer.order(ByteOrder.nativeOrder());
+            }
+
+            @Override
+            public int getRowStride() {
+                if (WriterSurfaceImage.this.isImageValid() == false) {
+                    throw new IllegalStateException("Image is already released");
+                }
+                return mRowStride;
+            }
+
+            @Override
+            public int getPixelStride() {
+                if (WriterSurfaceImage.this.isImageValid() == false) {
+                    throw new IllegalStateException("Image is already released");
+                }
+                return mPixelStride;
+            }
+
+            @Override
+            public ByteBuffer getBuffer() {
+                if (WriterSurfaceImage.this.isImageValid() == false) {
+                    throw new IllegalStateException("Image is already released");
+                }
+
+                return mBuffer;
+            }
+
+            private void clearBuffer() {
+                // Need null check first, as the getBuffer() may not be called
+                // before an Image is closed.
+                if (mBuffer == null) {
+                    return;
+                }
+
+                if (mBuffer.isDirect()) {
+                    NioUtils.freeDirectBuffer(mBuffer);
+                }
+                mBuffer = null;
+            }
+
+        }
+
+        // this will create the SurfacePlane object and fill the information
+        private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt);
+
+        private synchronized native int nativeGetWidth();
+
+        private synchronized native int nativeGetHeight();
+
+        private synchronized native int nativeGetFormat();
+    }
+
+    // Native implemented ImageWriter methods.
+    private synchronized native long nativeInit(Object weakSelf, Surface surface, int maxImgs);
+
+    private synchronized native void nativeClose(long nativeCtx);
+
+    private synchronized native void nativeAttachImage(long nativeCtx, Image image);
+
+    private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi);
+
+    private synchronized native void nativeQueueInputImage(long nativeCtx, Image image,
+            long timestampNs, int left, int top, int right, int bottom);
+
+    private synchronized native void cancelImage(long nativeCtx, Image image);
+
+    /**
+     * We use a class initializer to allow the native code to cache some field
+     * offsets.
+     */
+    private static native void nativeClassInit();
+
+    static {
+        System.loadLibrary("media_jni");
+        nativeClassInit();
+    }
+}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 6b37a34..069f7ff 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -82,6 +82,10 @@
  * encrypted content, the samples returned from the extractor remain encrypted, they
  * are only decrypted when the samples are delivered to the decoder.
  * <p>
+ * MediaDrm methods throw {@link java.lang.IllegalStateException}
+ * when a method is called on a MediaDrm object that is in an invalid or inoperable
+ * state. This is typically due to incorrect application API usage, but may also
+ * be due to an unrecoverable failure in the DRM plugin or security hardware.
  * <a name="Callbacks"></a>
  * <h3>Callbacks</h3>
  * <p>Applications should register for informational events in order
@@ -383,11 +387,27 @@
     public static final int KEY_TYPE_RELEASE = 3;
 
     /**
+     * Key request type is initial license request
+     */
+    public static final int REQUEST_TYPE_INITIAL = 0;
+
+    /**
+     * Key request type is license renewal
+     */
+    public static final int REQUEST_TYPE_RENEWAL = 1;
+
+    /**
+     * Key request type is license release
+     */
+    public static final int REQUEST_TYPE_RELEASE = 2;
+
+    /**
      * Contains the opaque data an app uses to request keys from a license server
      */
     public final static class KeyRequest {
         private byte[] mData;
         private String mDefaultUrl;
+        private int mRequestType;
 
         KeyRequest() {}
 
@@ -402,6 +422,11 @@
          * server URL from other sources.
          */
         public String getDefaultUrl() { return mDefaultUrl; }
+
+        /**
+         * Get the type of the request
+         */
+        public int getRequestType() { return mRequestType; }
     };
 
     /**
@@ -460,7 +485,6 @@
      * reprovisioning is required
      * @throws DeniedByServerException if the response indicates that the
      * server rejected the request
-     * @throws ResourceBusyException if required resources are in use
      */
     public native byte[] provideKeyResponse(byte[] scope, byte[] response)
             throws NotProvisionedException, DeniedByServerException;
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 438e767..936762c 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1054,6 +1054,50 @@
         public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
 
         /**
+         * Internal integer flag used by individual TV input services.
+         * <p>
+         * This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         * </p><p>
+         * Type: INTEGER
+         * </p>
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         * <p>
+         * This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         * </p><p>
+         * Type: INTEGER
+         * </p>
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         * <p>
+         * This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         * </p><p>
+         * Type: INTEGER
+         * </p>
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         * <p>
+         * This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         * </p><p>
+         * Type: INTEGER
+         * </p>
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+
+        /**
          * The version number of this row entry used by TV input services.
          * <p>
          * This is best used by sync adapters to identify the rows to update. The number can be
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index cf1b441..b887855 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -1223,6 +1223,8 @@
                     args.arg2 = mProxySession;
                     args.arg3 = mProxySessionCallback;
                     args.arg4 = session.getToken();
+                    session.tune(TvContract.buildChannelUriForPassthroughInput(
+                            getHardwareInputId()));
                 } else {
                     args.arg1 = null;
                     args.arg2 = null;
@@ -1232,7 +1234,6 @@
                 }
                 mServiceHandler.obtainMessage(ServiceHandler.DO_NOTIFY_SESSION_CREATED, args)
                         .sendToTarget();
-                session.tune(TvContract.buildChannelUriForPassthroughInput(getHardwareInputId()));
             }
 
             @Override
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 4ebbe26..dae57a8 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -2,6 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+    android_media_ImageWriter.cpp \
     android_media_ImageReader.cpp \
     android_media_MediaCrypto.cpp \
     android_media_MediaCodec.cpp \
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index b247493..9fc7e8e 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -860,6 +860,25 @@
     return ACQUIRE_SUCCESS;
 }
 
+static void ImageReader_detachImage(JNIEnv* env, jobject thiz, jobject image) {
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", "ImageReader was already closed");
+        return;
+    }
+
+    // CpuConsumer* consumer = ctx->getCpuConsumer();
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image);
+    if (!buffer) {
+        ALOGW("Image already released!!!");
+        return;
+    }
+
+    // TODO: need implement
+    jniThrowRuntimeException(env, "nativeDetachImage is not implemented yet!!!");
+}
+
 static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
 {
     ALOGV("%s: ", __FUNCTION__);
@@ -961,6 +980,7 @@
     {"nativeReleaseImage",     "(Landroid/media/Image;)V",   (void*)ImageReader_imageRelease },
     {"nativeImageSetup",       "(Landroid/media/Image;)I",   (void*)ImageReader_imageSetup },
     {"nativeGetSurface",       "()Landroid/view/Surface;",   (void*)ImageReader_getSurface },
+    {"nativeDetachImage",      "(Landroid/media/Image;)V",   (void*)ImageReader_detachImage },
 };
 
 static JNINativeMethod gImageMethods[] = {
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
new file mode 100644
index 0000000..d10df3e
--- /dev/null
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -0,0 +1,1014 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ImageWriter_JNI"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <gui/IProducerListener.h>
+#include <gui/Surface.h>
+#include <gui/CpuConsumer.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
+#include <camera3.h>
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#include <stdint.h>
+#include <inttypes.h>
+
+#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
+
+#define IMAGE_BUFFER_JNI_ID           "mNativeBuffer"
+
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+enum {
+    IMAGE_WRITER_MAX_NUM_PLANES = 3,
+};
+
+static struct {
+    jmethodID postEventFromNative;
+    jfieldID mWriterFormat;
+} gImageWriterClassInfo;
+
+static struct {
+    jfieldID mNativeBuffer;
+    jfieldID mNativeFenceFd;
+    jfieldID mPlanes;
+} gSurfaceImageClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gSurfacePlaneClassInfo;
+
+typedef CpuConsumer::LockedBuffer LockedImage;
+
+// ----------------------------------------------------------------------------
+
+class JNIImageWriterContext : public BnProducerListener {
+public:
+    JNIImageWriterContext(JNIEnv* env, jobject weakThiz, jclass clazz);
+
+    virtual ~JNIImageWriterContext();
+
+    // Implementation of IProducerListener, used to notify the ImageWriter that the consumer
+    // has returned a buffer and it is ready for ImageWriter to dequeue.
+    virtual void onBufferReleased();
+
+    void setProducer(const sp<ANativeWindow>& producer) { mProducer = producer; }
+    ANativeWindow* getProducer() { return mProducer.get(); }
+
+    void setBufferFormat(int format) { mFormat = format; }
+    int getBufferFormat() { return mFormat; }
+
+    void setBufferWidth(int width) { mWidth = width; }
+    int getBufferWidth() { return mWidth; }
+
+    void setBufferHeight(int height) { mHeight = height; }
+    int getBufferHeight() { return mHeight; }
+
+private:
+    static JNIEnv* getJNIEnv(bool* needsDetach);
+    static void detachJNI();
+
+    sp<ANativeWindow> mProducer;
+    jobject mWeakThiz;
+    jclass mClazz;
+    int mFormat;
+    int mWidth;
+    int mHeight;
+};
+
+JNIImageWriterContext::JNIImageWriterContext(JNIEnv* env, jobject weakThiz, jclass clazz) :
+    mWeakThiz(env->NewGlobalRef(weakThiz)),
+    mClazz((jclass)env->NewGlobalRef(clazz)),
+    mFormat(0),
+    mWidth(-1),
+    mHeight(-1) {
+}
+
+JNIImageWriterContext::~JNIImageWriterContext() {
+    ALOGV("%s", __FUNCTION__);
+    bool needsDetach = false;
+    JNIEnv* env = getJNIEnv(&needsDetach);
+    if (env != NULL) {
+        env->DeleteGlobalRef(mWeakThiz);
+        env->DeleteGlobalRef(mClazz);
+    } else {
+        ALOGW("leaking JNI object references");
+    }
+    if (needsDetach) {
+        detachJNI();
+    }
+
+    mProducer.clear();
+}
+
+JNIEnv* JNIImageWriterContext::getJNIEnv(bool* needsDetach) {
+    ALOGV("%s", __FUNCTION__);
+    LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!");
+    *needsDetach = false;
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (env == NULL) {
+        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+        JavaVM* vm = AndroidRuntime::getJavaVM();
+        int result = vm->AttachCurrentThread(&env, (void*) &args);
+        if (result != JNI_OK) {
+            ALOGE("thread attach failed: %#x", result);
+            return NULL;
+        }
+        *needsDetach = true;
+    }
+    return env;
+}
+
+void JNIImageWriterContext::detachJNI() {
+    ALOGV("%s", __FUNCTION__);
+    JavaVM* vm = AndroidRuntime::getJavaVM();
+    int result = vm->DetachCurrentThread();
+    if (result != JNI_OK) {
+        ALOGE("thread detach failed: %#x", result);
+    }
+}
+
+void JNIImageWriterContext::onBufferReleased() {
+    ALOGV("%s: buffer released", __FUNCTION__);
+    bool needsDetach = false;
+    JNIEnv* env = getJNIEnv(&needsDetach);
+    if (env != NULL) {
+        env->CallStaticVoidMethod(mClazz, gImageWriterClassInfo.postEventFromNative, mWeakThiz);
+    } else {
+        ALOGW("onBufferReleased event will not posted");
+    }
+    if (needsDetach) {
+        detachJNI();
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+extern "C" {
+
+// -------------------------------Private method declarations--------------
+
+static bool isWritable(int format);
+static bool isPossiblyYUV(PixelFormat format);
+static void Image_setNativeContext(JNIEnv* env, jobject thiz,
+        sp<GraphicBuffer> buffer, int fenceFd);
+static void Image_getNativeContext(JNIEnv* env, jobject thiz,
+        GraphicBuffer** buffer, int* fenceFd);
+static void Image_unlockIfLocked(JNIEnv* env, jobject thiz);
+
+// --------------------------ImageWriter methods---------------------------------------
+
+static void ImageWriter_classInit(JNIEnv* env, jclass clazz) {
+    ALOGV("%s:", __FUNCTION__);
+    jclass imageClazz = env->FindClass("android/media/ImageWriter$WriterSurfaceImage");
+    LOG_ALWAYS_FATAL_IF(imageClazz == NULL,
+            "can't find android/media/ImageWriter$WriterSurfaceImage");
+    gSurfaceImageClassInfo.mNativeBuffer = env->GetFieldID(
+            imageClazz, IMAGE_BUFFER_JNI_ID, "J");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeBuffer == NULL,
+            "can't find android/media/ImageWriter$WriterSurfaceImage.%s", IMAGE_BUFFER_JNI_ID);
+
+    gSurfaceImageClassInfo.mNativeFenceFd = env->GetFieldID(
+            imageClazz, "mNativeFenceFd", "I");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mNativeFenceFd == NULL,
+            "can't find android/media/ImageWriter$WriterSurfaceImage.mNativeFenceFd");
+
+    gSurfaceImageClassInfo.mPlanes = env->GetFieldID(
+            imageClazz, "mPlanes", "[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mPlanes == NULL,
+            "can't find android/media/ImageWriter$WriterSurfaceImage.mPlanes");
+
+    gImageWriterClassInfo.postEventFromNative = env->GetStaticMethodID(
+            clazz, "postEventFromNative", "(Ljava/lang/Object;)V");
+    LOG_ALWAYS_FATAL_IF(gImageWriterClassInfo.postEventFromNative == NULL,
+                        "can't find android/media/ImageWriter.postEventFromNative");
+
+    gImageWriterClassInfo.mWriterFormat = env->GetFieldID(
+            clazz, "mWriterFormat", "I");
+    LOG_ALWAYS_FATAL_IF(gImageWriterClassInfo.mWriterFormat == NULL,
+                        "can't find android/media/ImageWriter.mWriterFormat");
+
+    jclass planeClazz = env->FindClass("android/media/ImageWriter$WriterSurfaceImage$SurfacePlane");
+    LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class");
+    // FindClass only gives a local reference of jclass object.
+    gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz);
+    gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>",
+            "(Landroid/media/ImageWriter$WriterSurfaceImage;IILjava/nio/ByteBuffer;)V");
+    LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL,
+            "Can not find SurfacePlane constructor");
+}
+
+static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobject jsurface,
+        jint maxImages) {
+    status_t res;
+
+    ALOGV("%s: maxImages:%d", __FUNCTION__, maxImages);
+
+    sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
+    if (surface == NULL) {
+        jniThrowException(env,
+                "java/lang/IllegalArgumentException",
+                "The surface has been released");
+        return 0;
+     }
+    sp<IGraphicBufferProducer> bufferProducer = surface->getIGraphicBufferProducer();
+
+    jclass clazz = env->GetObjectClass(thiz);
+    if (clazz == NULL) {
+        jniThrowRuntimeException(env, "Can't find android/graphics/ImageWriter");
+        return 0;
+    }
+    sp<JNIImageWriterContext> ctx(new JNIImageWriterContext(env, weakThiz, clazz));
+
+    sp<Surface> producer = new Surface(bufferProducer, /*controlledByApp*/false);
+    ctx->setProducer(producer);
+    /**
+     * NATIVE_WINDOW_API_CPU isn't a good choice here, as it makes the bufferQueue not connectable
+     * after disconnect. MEDIA or CAMERA are treated the same internally. The producer listener
+     * will be cleared after disconnect call.
+     */
+    producer->connect(/*api*/NATIVE_WINDOW_API_CAMERA, /*listener*/ctx);
+    jlong nativeCtx = reinterpret_cast<jlong>(ctx.get());
+
+    // Get the dimension and format of the producer.
+    sp<ANativeWindow> anw = producer;
+    int32_t width, height, format;
+    if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
+        ALOGE("%s: Query Surface width failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "Failed to query Surface width");
+        return 0;
+    }
+    ctx->setBufferWidth(width);
+
+    if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
+        ALOGE("%s: Query Surface height failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "Failed to query Surface height");
+        return 0;
+    }
+    ctx->setBufferHeight(height);
+
+    if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
+        ALOGE("%s: Query Surface format failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "Failed to query Surface format");
+        return 0;
+    }
+    ctx->setBufferFormat(format);
+    env->SetIntField(thiz, gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(format));
+
+
+    if (isWritable(format)) {
+        res = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN);
+        if (res != OK) {
+            ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)",
+                    __FUNCTION__, GRALLOC_USAGE_SW_WRITE_OFTEN, format, strerror(-res), res);
+            jniThrowRuntimeException(env, "Failed to SW_WRITE_OFTEN configure usage");
+            return 0;
+        }
+    }
+
+    int minUndequeuedBufferCount = 0;
+    res = anw->query(anw.get(),
+                NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufferCount);
+    if (res != OK) {
+        ALOGE("%s: Query producer undequeued buffer count failed: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "Query producer undequeued buffer count failed");
+        return 0;
+     }
+
+    size_t totalBufferCount = maxImages + minUndequeuedBufferCount;
+    res = native_window_set_buffer_count(anw.get(), totalBufferCount);
+    if (res != OK) {
+        ALOGE("%s: Set buffer count failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "Set buffer count failed");
+        return 0;
+    }
+
+    if (ctx != 0) {
+        ctx->incStrong((void*)ImageWriter_init);
+    }
+    return nativeCtx;
+}
+
+static void ImageWriter_dequeueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image) {
+    ALOGV("%s", __FUNCTION__);
+    JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
+    if (ctx == NULL || thiz == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageWriterContext is not initialized");
+        return;
+    }
+
+    sp<ANativeWindow> anw = ctx->getProducer();
+    android_native_buffer_t *anb = NULL;
+    int fenceFd = -1;
+    status_t res = anw->dequeueBuffer(anw.get(), &anb, &fenceFd);
+    if (res != OK) {
+        // TODO: handle different error cases here.
+        ALOGE("%s: Set buffer count failed: %s (%d)", __FUNCTION__, strerror(-res), res);
+        jniThrowRuntimeException(env, "dequeue buffer failed");
+        return;
+    }
+    // New GraphicBuffer object doesn't own the handle, thus the native buffer
+    // won't be freed when this object is destroyed.
+    sp<GraphicBuffer> buffer(new GraphicBuffer(anb, /*keepOwnership*/false));
+
+    // Note that:
+    // 1. No need to lock buffer now, will only lock it when the first getPlanes() is called.
+    // 2. Fence will be saved to mNativeFenceFd, and will consumed by lock/queue/cancel buffer
+    //    later.
+    // 3. need use lockAsync here, as it will handle the dequeued fence for us automatically.
+
+    // Finally, set the native info into image object.
+    Image_setNativeContext(env, image, buffer, fenceFd);
+}
+
+static void ImageWriter_close(JNIEnv* env, jobject thiz, jlong nativeCtx) {
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
+    if (ctx == NULL || thiz == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageWriterContext is not initialized");
+        return;
+    }
+
+    ANativeWindow* producer = ctx->getProducer();
+    if (producer != NULL) {
+        /**
+         * NATIVE_WINDOW_API_CPU isn't a good choice here, as it makes the bufferQueue not
+         * connectable after disconnect. MEDIA or CAMERA are treated the same internally.
+         * The producer listener will be cleared after disconnect call.
+         */
+        status_t res = native_window_api_disconnect(producer, /*api*/NATIVE_WINDOW_API_CAMERA);
+        /**
+         * This is not an error. if client calling process dies, the window will
+         * also die and all calls to it will return DEAD_OBJECT, thus it's already
+         * "disconnected"
+         */
+        if (res == DEAD_OBJECT) {
+            ALOGW("%s: While disconnecting ImageWriter from native window, the"
+                    " native window died already", __FUNCTION__);
+        } else if (res != OK) {
+            ALOGE("%s: native window disconnect failed: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            jniThrowRuntimeException(env, "Native window disconnect failed");
+            return;
+        }
+    }
+
+    ctx->decStrong((void*)ImageWriter_init);
+}
+
+static void ImageWriter_cancelImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image) {
+    ALOGV("%s", __FUNCTION__);
+    JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
+    if (ctx == NULL || thiz == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageWriterContext is not initialized");
+        return;
+    }
+
+    sp<ANativeWindow> anw = ctx->getProducer();
+
+    GraphicBuffer *buffer = NULL;
+    int fenceFd = -1;
+    Image_getNativeContext(env, image, &buffer, &fenceFd);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return;
+    }
+
+    // Unlock the image if it was locked
+    Image_unlockIfLocked(env, image);
+
+    anw->cancelBuffer(anw.get(), buffer, fenceFd);
+
+    Image_setNativeContext(env, image, NULL, -1);
+}
+
+static void ImageWriter_queueImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image,
+        jlong timestampNs, jint left, jint top, jint right, jint bottom) {
+    ALOGV("%s", __FUNCTION__);
+    JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
+    if (ctx == NULL || thiz == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageWriterContext is not initialized");
+        return;
+    }
+
+    status_t res = OK;
+    sp<ANativeWindow> anw = ctx->getProducer();
+
+    GraphicBuffer *buffer = NULL;
+    int fenceFd = -1;
+    Image_getNativeContext(env, image, &buffer, &fenceFd);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return;
+    }
+
+    // Unlock image if it was locked.
+    Image_unlockIfLocked(env, image);
+
+    // Set timestamp
+    ALOGV("timestamp to be queued: %" PRId64, timestampNs);
+    res = native_window_set_buffers_timestamp(anw.get(), timestampNs);
+    if (res != OK) {
+        jniThrowRuntimeException(env, "Set timestamp failed");
+        return;
+    }
+
+    // Set crop
+    android_native_rect_t cropRect;
+    cropRect.left = left;
+    cropRect.top = top;
+    cropRect.right = right;
+    cropRect.bottom = bottom;
+    res = native_window_set_crop(anw.get(), &cropRect);
+    if (res != OK) {
+        jniThrowRuntimeException(env, "Set crop rect failed");
+        return;
+    }
+
+    // Finally, queue input buffer
+    res = anw->queueBuffer(anw.get(), buffer, fenceFd);
+    if (res != OK) {
+        jniThrowRuntimeException(env, "Queue input buffer failed");
+        return;
+    }
+
+    Image_setNativeContext(env, image, NULL, -1);
+}
+
+static void ImageWriter_attachImage(JNIEnv* env, jobject thiz, jlong nativeCtx, jobject image) {
+    ALOGV("%s", __FUNCTION__);
+    JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
+    if (ctx == NULL || thiz == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageWriterContext is not initialized");
+        return;
+    }
+
+    sp<ANativeWindow> anw = ctx->getProducer();
+
+    GraphicBuffer *buffer = NULL;
+    int fenceFd = -1;
+    Image_getNativeContext(env, image, &buffer, &fenceFd);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return;
+    }
+
+    // TODO: need implement
+    jniThrowRuntimeException(env, "nativeAttachImage is not implement yet!!!");
+}
+
+// --------------------------Image methods---------------------------------------
+
+static void Image_getNativeContext(JNIEnv* env, jobject thiz,
+        GraphicBuffer** buffer, int* fenceFd) {
+    ALOGV("%s", __FUNCTION__);
+    if (buffer != NULL) {
+        GraphicBuffer *gb = reinterpret_cast<GraphicBuffer *>
+                  (env->GetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer));
+        *buffer = gb;
+    }
+
+    if (fenceFd != NULL) {
+        *fenceFd = reinterpret_cast<jint>(env->GetIntField(
+                thiz, gSurfaceImageClassInfo.mNativeFenceFd));
+    }
+}
+
+static void Image_setNativeContext(JNIEnv* env, jobject thiz,
+        sp<GraphicBuffer> buffer, int fenceFd) {
+    ALOGV("%s:", __FUNCTION__);
+    GraphicBuffer* p = NULL;
+    Image_getNativeContext(env, thiz, &p, /*fenceFd*/NULL);
+    if (buffer != 0) {
+        buffer->incStrong((void*)Image_setNativeContext);
+    }
+    if (p) {
+        p->decStrong((void*)Image_setNativeContext);
+    }
+    env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer,
+            reinterpret_cast<jlong>(buffer.get()));
+
+    env->SetIntField(thiz, gSurfaceImageClassInfo.mNativeFenceFd, reinterpret_cast<jint>(fenceFd));
+}
+
+static void Image_unlockIfLocked(JNIEnv* env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+    GraphicBuffer* buffer;
+    Image_getNativeContext(env, thiz, &buffer, NULL);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return;
+    }
+
+    // Is locked?
+    bool isLocked = false;
+    jobject planes = env->GetObjectField(thiz, gSurfaceImageClassInfo.mPlanes);
+    isLocked = (planes != NULL);
+    if (isLocked) {
+        // no need to use fence here, as we it will be consumed by either concel or queue buffer.
+        status_t res = buffer->unlock();
+        if (res != OK) {
+            jniThrowRuntimeException(env, "unlock buffer failed");
+        }
+        ALOGV("Successfully unlocked the image");
+    }
+}
+
+static jint Image_getWidth(JNIEnv* env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+    GraphicBuffer* buffer;
+    Image_getNativeContext(env, thiz, &buffer, NULL);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return -1;
+    }
+
+    return buffer->getWidth();
+}
+
+static jint Image_getHeight(JNIEnv* env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+    GraphicBuffer* buffer;
+    Image_getNativeContext(env, thiz, &buffer, NULL);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return -1;
+    }
+
+    return buffer->getHeight();
+}
+
+// Some formats like JPEG defined with different values between android.graphics.ImageFormat and
+// graphics.h, need convert to the one defined in graphics.h here.
+static int Image_getPixelFormat(JNIEnv* env, int format) {
+    int jpegFormat;
+    jfieldID fid;
+
+    ALOGV("%s: format = 0x%x", __FUNCTION__, format);
+
+    jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat");
+    ALOG_ASSERT(imageFormatClazz != NULL);
+
+    fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I");
+    jpegFormat = env->GetStaticIntField(imageFormatClazz, fid);
+
+    // Translate the JPEG to BLOB for camera purpose.
+    if (format == jpegFormat) {
+        format = HAL_PIXEL_FORMAT_BLOB;
+    }
+
+    return format;
+}
+
+static jint Image_getFormat(JNIEnv* env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+    GraphicBuffer* buffer;
+    Image_getNativeContext(env, thiz, &buffer, NULL);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return 0;
+    }
+
+    return Image_getPixelFormat(env, buffer->getPixelFormat());
+}
+
+static void Image_setFenceFd(JNIEnv* env, jobject thiz, int fenceFd) {
+    ALOGV("%s:", __FUNCTION__);
+    env->SetIntField(thiz, gSurfaceImageClassInfo.mNativeFenceFd, reinterpret_cast<jint>(fenceFd));
+}
+
+static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) {
+    ALOGV("%s", __FUNCTION__);
+    GraphicBuffer* buffer;
+    int fenceFd = -1;
+    Image_getNativeContext(env, thiz, &buffer, &fenceFd);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return;
+    }
+
+    void* pData = NULL;
+    android_ycbcr ycbcr = android_ycbcr();
+    status_t res;
+    int format = Image_getFormat(env, thiz);
+    int flexFormat = format;
+    if (isPossiblyYUV(format)) {
+        // ImageWriter doesn't use crop by itself, app sets it, use the no crop version.
+        res = buffer->lockAsyncYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr, fenceFd);
+        // Clear the fenceFd as it is already consumed by lock call.
+        Image_setFenceFd(env, thiz, /*fenceFd*/-1);
+        if (res != OK) {
+            jniThrowRuntimeException(env, "lockAsyncYCbCr failed for YUV buffer");
+            return;
+        }
+        pData = ycbcr.y;
+        flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+    }
+
+    // lockAsyncYCbCr for YUV is unsuccessful.
+    if (pData == NULL) {
+        res = buffer->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &pData, fenceFd);
+        if (res != OK) {
+            jniThrowRuntimeException(env, "lockAsync failed");
+            return;
+        }
+    }
+
+    image->data = reinterpret_cast<uint8_t*>(pData);
+    image->width = buffer->getWidth();
+    image->height = buffer->getHeight();
+    image->format = format;
+    image->flexFormat = flexFormat;
+    image->stride = (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride();
+
+    image->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
+    image->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr);
+    image->chromaStride = static_cast<uint32_t>(ycbcr.cstride);
+    image->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step);
+    ALOGV("Successfully locked the image");
+    // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer,
+    // and we don't set them here.
+}
+
+static bool usingRGBAToJpegOverride(int32_t bufferFormat, int32_t writerCtxFormat) {
+    return writerCtxFormat == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888;
+}
+
+static int32_t applyFormatOverrides(int32_t bufferFormat, int32_t writerCtxFormat)
+{
+    // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW
+    // write limitations for some platforms (b/17379185).
+    if (usingRGBAToJpegOverride(bufferFormat, writerCtxFormat)) {
+        return HAL_PIXEL_FORMAT_BLOB;
+    }
+    return bufferFormat;
+}
+
+static uint32_t Image_getJpegSize(LockedImage* buffer, bool usingRGBAOverride) {
+    ALOGV("%s", __FUNCTION__);
+    ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
+    uint32_t size = 0;
+    uint32_t width = buffer->width;
+    uint8_t* jpegBuffer = buffer->data;
+
+    if (usingRGBAOverride) {
+        width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4;
+    }
+
+    // First check for JPEG transport header at the end of the buffer
+    uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
+    struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header);
+    if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
+        size = blob->jpeg_size;
+        ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
+    }
+
+    // failed to find size, default to whole buffer
+    if (size == 0) {
+        /*
+         * This is a problem because not including the JPEG header
+         * means that in certain rare situations a regular JPEG blob
+         * will be misidentified as having a header, in which case
+         * we will get a garbage size value.
+         */
+        ALOGW("%s: No JPEG header detected, defaulting to size=width=%d",
+                __FUNCTION__, width);
+        size = width;
+    }
+
+    return size;
+}
+
+static void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
+        int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) {
+    ALOGV("%s", __FUNCTION__);
+    ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
+    ALOG_ASSERT(base != NULL, "base is NULL!!!");
+    ALOG_ASSERT(size != NULL, "size is NULL!!!");
+    ALOG_ASSERT(pixelStride != NULL, "pixelStride is NULL!!!");
+    ALOG_ASSERT(rowStride != NULL, "rowStride is NULL!!!");
+    ALOG_ASSERT((idx < IMAGE_WRITER_MAX_NUM_PLANES) && (idx >= 0));
+
+    ALOGV("%s: buffer: %p", __FUNCTION__, buffer);
+
+    uint32_t dataSize, ySize, cSize, cStride;
+    uint32_t pStride = 0, rStride = 0;
+    uint8_t *cb, *cr;
+    uint8_t *pData = NULL;
+    int bytesPerPixel = 0;
+
+    dataSize = ySize = cSize = cStride = 0;
+    int32_t fmt = buffer->flexFormat;
+
+    bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, writerFormat);
+    fmt = applyFormatOverrides(fmt, writerFormat);
+    switch (fmt) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    buffer->dataCb :
+                buffer->dataCr;
+            // only map until last pixel
+            if (idx == 0) {
+                pStride = 1;
+                rStride = buffer->stride;
+                dataSize = buffer->stride * (buffer->height - 1) + buffer->width;
+            } else {
+                pStride = buffer->chromaStep;
+                rStride = buffer->chromaStride;
+                dataSize = buffer->chromaStride * (buffer->height / 2 - 1) +
+                        buffer->chromaStep * (buffer->width / 2 - 1) + 1;
+            }
+            break;
+        // NV21
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            cr = buffer->data + (buffer->stride * buffer->height);
+            cb = cr + 1;
+            // only map until last pixel
+            ySize = buffer->width * (buffer->height - 1) + buffer->width;
+            cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1;
+
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    cb:
+                cr;
+
+            dataSize = (idx == 0) ? ySize : cSize;
+            pStride = (idx == 0) ? 1 : 2;
+            rStride = buffer->width;
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            // Y and C stride need to be 16 pixel aligned.
+            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
+                                "Stride is not 16 pixel aligned %d", buffer->stride);
+
+            ySize = buffer->stride * buffer->height;
+            cStride = ALIGN(buffer->stride / 2, 16);
+            cr = buffer->data + ySize;
+            cSize = cStride * buffer->height / 2;
+            cb = cr + cSize;
+
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    cb :
+                cr;
+            dataSize = (idx == 0) ? ySize : cSize;
+            pStride = 1;
+            rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16);
+            break;
+        case HAL_PIXEL_FORMAT_Y8:
+            // Single plane, 8bpp.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height;
+            pStride = 1;
+            rStride = buffer->stride;
+            break;
+        case HAL_PIXEL_FORMAT_Y16:
+            bytesPerPixel = 2;
+            // Single plane, 16bpp, strides are specified in pixels, not in bytes
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            pStride = bytesPerPixel;
+            rStride = buffer->stride * 2;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            // Used for JPEG data, height must be 1, width == size, single plane.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height);
+
+            pData = buffer->data;
+            dataSize = Image_getJpegSize(buffer, usingRGBAOverride);
+            pStride = bytesPerPixel;
+            rowStride = 0;
+            break;
+        case HAL_PIXEL_FORMAT_RAW16:
+            // Single plane 16bpp bayer data.
+            bytesPerPixel = 2;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            pStride = bytesPerPixel;
+            rStride = buffer->stride * 2;
+            break;
+        case HAL_PIXEL_FORMAT_RAW10:
+            // Single plane 10bpp bayer data.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            LOG_ALWAYS_FATAL_IF(buffer->width % 4,
+                                "Width is not multiple of 4 %d", buffer->width);
+            LOG_ALWAYS_FATAL_IF(buffer->height % 2,
+                                "Height is not even %d", buffer->height);
+            LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8),
+                                "stride (%d) should be at least %d",
+                                buffer->stride, buffer->width * 10 / 8);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height;
+            pStride = 0;
+            rStride = buffer->stride;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            // Single plane, 32bpp.
+            bytesPerPixel = 4;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            pStride = bytesPerPixel;
+            rStride = buffer->stride * 4;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            // Single plane, 16bpp.
+            bytesPerPixel = 2;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            pStride = bytesPerPixel;
+            rStride = buffer->stride * 2;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            // Single plane, 24bpp.
+            bytesPerPixel = 3;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            pStride = bytesPerPixel;
+            rStride = buffer->stride * 3;
+            break;
+        default:
+            jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
+                                 "Pixel format: 0x%x is unsupported", fmt);
+            break;
+    }
+
+    *base = pData;
+    *size = dataSize;
+    *pixelStride = pStride;
+    *rowStride = rStride;
+}
+
+static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
+        int numPlanes, int writerFormat) {
+    ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
+    int rowStride, pixelStride;
+    uint8_t *pData;
+    uint32_t dataSize;
+    jobject byteBuffer;
+
+    int format = Image_getFormat(env, thiz);
+    if (!isWritable(format) && numPlanes > 0) {
+        String8 msg;
+        msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)"
+                " must be 0", format, numPlanes);
+        jniThrowException(env, "java/lang/IllegalArgumentException", msg.string());
+        return NULL;
+    }
+
+    jobjectArray surfacePlanes = env->NewObjectArray(numPlanes, gSurfacePlaneClassInfo.clazz,
+            /*initial_element*/NULL);
+    if (surfacePlanes == NULL) {
+        jniThrowRuntimeException(env, "Failed to create SurfacePlane arrays,"
+                " probably out of memory");
+        return NULL;
+    }
+
+    // Buildup buffer info: rowStride, pixelStride and byteBuffers.
+    LockedImage lockedImg = LockedImage();
+    Image_getLockedImage(env, thiz, &lockedImg);
+
+    // Create all SurfacePlanes
+    writerFormat = Image_getPixelFormat(env, writerFormat);
+    for (int i = 0; i < numPlanes; i++) {
+        Image_getLockedImageInfo(env, &lockedImg, i, writerFormat,
+                &pData, &dataSize, &pixelStride, &rowStride);
+        byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
+        if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) {
+            jniThrowException(env, "java/lang/IllegalStateException",
+                    "Failed to allocate ByteBuffer");
+            return NULL;
+        }
+
+        // Finally, create this SurfacePlane.
+        jobject surfacePlane = env->NewObject(gSurfacePlaneClassInfo.clazz,
+                    gSurfacePlaneClassInfo.ctor, thiz, rowStride, pixelStride, byteBuffer);
+        env->SetObjectArrayElement(surfacePlanes, i, surfacePlane);
+    }
+
+    return surfacePlanes;
+}
+
+// -------------------------------Private convenience methods--------------------
+
+// Check if buffer with this format is writable. Generally speaking, the opaque formats
+// like IMPLEMENTATION_DEFINED is not writable, as the actual buffer formats and layouts
+// are unknown to frameworks.
+static bool isWritable(int format) {
+    // Assume all other formats are writable.
+    return !(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+            format == HAL_PIXEL_FORMAT_RAW_OPAQUE);
+}
+
+static bool isPossiblyYUV(PixelFormat format) {
+    switch (static_cast<int>(format)) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_Y8:
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW16:
+        case HAL_PIXEL_FORMAT_RAW10:
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+            return false;
+
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        default:
+            return true;
+    }
+}
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gImageWriterMethods[] = {
+    {"nativeClassInit",         "()V",                        (void*)ImageWriter_classInit },
+    {"nativeInit",              "(Ljava/lang/Object;Landroid/view/Surface;I)J",
+                                                              (void*)ImageWriter_init },
+    {"nativeClose",              "(J)V",                       (void*)ImageWriter_close },
+    {"nativeAttachImage",       "(JLandroid/media/Image;)V",  (void*)ImageWriter_attachImage },
+    {"nativeDequeueInputImage", "(JLandroid/media/Image;)V",  (void*)ImageWriter_dequeueImage },
+    {"nativeQueueInputImage",   "(JLandroid/media/Image;JIIII)V",  (void*)ImageWriter_queueImage },
+    {"cancelImage",             "(JLandroid/media/Image;)V",   (void*)ImageWriter_cancelImage },
+};
+
+static JNINativeMethod gImageMethods[] = {
+    {"nativeCreatePlanes",      "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
+                                                              (void*)Image_createSurfacePlanes },
+    {"nativeGetWidth",         "()I",                         (void*)Image_getWidth },
+    {"nativeGetHeight",        "()I",                         (void*)Image_getHeight },
+    {"nativeGetFormat",        "()I",                         (void*)Image_getFormat },
+};
+
+int register_android_media_ImageWriter(JNIEnv *env) {
+
+    int ret1 = AndroidRuntime::registerNativeMethods(env,
+                   "android/media/ImageWriter", gImageWriterMethods, NELEM(gImageWriterMethods));
+
+    int ret2 = AndroidRuntime::registerNativeMethods(env,
+                   "android/media/ImageWriter$WriterSurfaceImage", gImageMethods, NELEM(gImageMethods));
+
+    return (ret1 || ret2);
+}
+
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 8302a34..96d7133 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -59,6 +59,7 @@
 struct RequestFields {
     jfieldID data;
     jfieldID defaultUrl;
+    jfieldID requestType;
 };
 
 struct ArrayListFields {
@@ -101,6 +102,12 @@
     jint kKeyTypeRelease;
 } gKeyTypes;
 
+struct KeyRequestTypes {
+    jint kKeyRequestTypeInitial;
+    jint kKeyRequestTypeRenewal;
+    jint kKeyRequestTypeRelease;
+} gKeyRequestTypes;
+
 struct CertificateTypes {
     jint kCertificateTypeNone;
     jint kCertificateTypeX509;
@@ -182,7 +189,7 @@
     jint jeventType;
 
     // translate DrmPlugin event types into their java equivalents
-    switch(eventType) {
+    switch (eventType) {
         case DrmPlugin::kDrmPluginEventProvisionRequired:
             jeventType = gEventTypes.kEventProvisionRequired;
             break;
@@ -236,7 +243,7 @@
 
     const char *drmMessage = NULL;
 
-    switch(err) {
+    switch (err) {
     case ERROR_DRM_UNKNOWN:
         drmMessage = "General DRM error";
         break;
@@ -587,6 +594,13 @@
     GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
     gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);
 
+    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
+    gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
+    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
+    gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
+    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
+    gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);
+
     GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
     gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
     GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
@@ -595,6 +609,7 @@
     FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
     GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
     GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
+    GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I");
 
     FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
     GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
@@ -786,9 +801,10 @@
 
     Vector<uint8_t> request;
     String8 defaultUrl;
+    DrmPlugin::KeyRequestType keyRequestType;
 
     status_t err = drm->getKeyRequest(sessionId, initData, mimeType,
-                                          keyType, optParams, request, defaultUrl);
+            keyType, optParams, request, defaultUrl, &keyRequestType);
 
     if (throwExceptionAsNecessary(env, err, "Failed to get key request")) {
         return NULL;
@@ -807,6 +823,25 @@
 
         jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
         env->SetObjectField(keyObj, gFields.keyRequest.defaultUrl, jdefaultUrl);
+
+        switch (keyRequestType) {
+            case DrmPlugin::kKeyRequestType_Initial:
+                env->SetIntField(keyObj, gFields.keyRequest.requestType,
+                        gKeyRequestTypes.kKeyRequestTypeInitial);
+                break;
+            case DrmPlugin::kKeyRequestType_Renewal:
+                env->SetIntField(keyObj, gFields.keyRequest.requestType,
+                        gKeyRequestTypes.kKeyRequestTypeRenewal);
+                break;
+            case DrmPlugin::kKeyRequestType_Release:
+                env->SetIntField(keyObj, gFields.keyRequest.requestType,
+                        gKeyRequestTypes.kKeyRequestTypeRelease);
+                break;
+            case DrmPlugin::kKeyRequestType_Unknown:
+                throwStateException(env, "DRM plugin failure: unknown key request type",
+                        ERROR_DRM_UNKNOWN);
+                break;
+        }
     }
 
     return keyObj;
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 55643f7..b748f3a 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -914,8 +914,8 @@
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
 }
-
 extern int register_android_media_ImageReader(JNIEnv *env);
+extern int register_android_media_ImageWriter(JNIEnv *env);
 extern int register_android_media_Crypto(JNIEnv *env);
 extern int register_android_media_Drm(JNIEnv *env);
 extern int register_android_media_MediaCodec(JNIEnv *env);
@@ -944,6 +944,11 @@
     }
     assert(env != NULL);
 
+    if (register_android_media_ImageWriter(env) != JNI_OK) {
+        ALOGE("ERROR: ImageWriter native registration failed");
+        goto bail;
+    }
+
     if (register_android_media_ImageReader(env) < 0) {
         ALOGE("ERROR: ImageReader native registration failed");
         goto bail;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 362bbc4..3bb5f01 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -20,8 +20,6 @@
 import android.hardware.ICamera;
 import android.hardware.ICameraClient;
 import android.hardware.ICameraServiceListener;
-import android.hardware.IProCameraCallbacks;
-import android.hardware.IProCameraUser;
 import android.hardware.camera2.ICameraDeviceCallbacks;
 import android.hardware.camera2.ICameraDeviceUser;
 import android.hardware.camera2.impl.CameraMetadataNative;
@@ -181,30 +179,6 @@
         }
     }
 
-    static class DummyProCameraCallbacks extends DummyBase implements IProCameraCallbacks {
-    }
-
-    @SmallTest
-    public void testConnectPro() throws Exception {
-        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
-
-            IProCameraCallbacks dummyCallbacks = new DummyProCameraCallbacks();
-
-            String clientPackageName = getContext().getPackageName();
-
-            BinderHolder holder = new BinderHolder();
-            CameraBinderDecorator.newInstance(mUtils.getCameraService())
-                    .connectPro(dummyCallbacks, cameraId,
-                    clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
-            IProCameraUser cameraUser = IProCameraUser.Stub.asInterface(holder.getBinder());
-            assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
-
-            Log.v(TAG, String.format("Camera %s connected", cameraId));
-
-            cameraUser.disconnect();
-        }
-    }
-
     @SmallTest
     public void testConnectLegacy() throws Exception {
         final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
diff --git a/packages/BackupRestoreConfirmation/res/values-en-rAU/strings.xml b/packages/BackupRestoreConfirmation/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..badad60
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-en-rAU/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="backup_confirm_title" msgid="827563724209303345">"Full backup"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Full restoration"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"A full backup of all data to a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the backup yourself, do not allow the operation to proceed."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Back up my data"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Do not back up"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"A full restore of all data from a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the restore yourself, do not allow the operation to proceed. This will replace any data currently on the device!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Restore my data"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Do not restore"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Please enter your current backup password below:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Please enter your device encryption password below."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Please enter your device encryption password below. This will also be used to encrypt the backup archive."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"If you wish to encrypt the full backup data, enter a password below:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"Since your device is encrypted, you are required to encrypt your backup. Please enter a password below:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"If the restore data is encrypted, please enter the password below:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Backup starting..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Backup finished"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Restoration starting..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Restoration ended"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Operation timed out"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
index 250f238..372ce76 100644
--- a/packages/CaptivePortalLogin/res/values-bg/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bg/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Директно използване на тази мрежа"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Вход в мрежата"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
index bca5ee9..9d13c2d 100644
--- a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে সাইন ইন করুন"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
index b20beee..5b35fcb 100644
--- a/packages/CaptivePortalLogin/res/values-ca/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ca/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Fes servir aquesta xarxa tal com està."</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Inicia la sessió a la xarxa"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-cs/strings.xml b/packages/CaptivePortalLogin/res/values-cs/strings.xml
index 37b744f..f9309d0 100644
--- a/packages/CaptivePortalLogin/res/values-cs/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-cs/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Použít tuto síť tak, jak je"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Přihlásit se k síti"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
index 4d1f534..ac796da 100644
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-de/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Dieses Netzwerk im Istzustand verwenden"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Dieses Netzwerk nicht verwenden"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..c1c03f8
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
index 4cfd382..63ce6e3 100644
--- a/packages/CaptivePortalLogin/res/values-es/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-es/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta red tal cual"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Iniciar sesión en la red"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml b/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml
index 07be36c..ed657aa 100644
--- a/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-eu-rES/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
index 4b012ce..d323b28 100644
--- a/packages/CaptivePortalLogin/res/values-fr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-fr/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Se connecter au réseau"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-gl-rES/strings.xml b/packages/CaptivePortalLogin/res/values-gl-rES/strings.xml
index c0c6c2d..a5a603f 100644
--- a/packages/CaptivePortalLogin/res/values-gl-rES/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-gl-rES/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede tal como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Inicia sesión na rede"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
index c543761..013f511 100644
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hi/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में प्रवेश करें"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
index 6c8f670..f2b2e75 100644
--- a/packages/CaptivePortalLogin/res/values-hr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hr/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
index 2fb6be6..26d3c87 100644
--- a/packages/CaptivePortalLogin/res/values-hu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hu/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Hálózat használata jelen állapotában"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne használja ezt a hálózatot"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Bejelentkezés a hálózatba"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-hy-rAM/strings.xml b/packages/CaptivePortalLogin/res/values-hy-rAM/strings.xml
index 02c23d4..570b927 100644
--- a/packages/CaptivePortalLogin/res/values-hy-rAM/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hy-rAM/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Օգտագործել այս ցանցն ինչպես կա"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Մուտք գործել ցանց"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
index b3c5890..15bbd4c 100644
--- a/packages/CaptivePortalLogin/res/values-ja/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ja/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"このネットワークをそのまま使用する"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"ネットワークにログイン"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml b/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml
index 8762b20..5918628 100644
--- a/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ka-rGE/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ამ ქსელის გამოყენება, როგორც არის"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"ქსელში შესვლა"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml b/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml
index fbce244..5e876a4 100644
--- a/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-kk-rKZ/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Осы желіні бар күйінде пайдалану"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Желіге кіру"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml b/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml
index 3c91fca..ae32c76 100644
--- a/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-km-rKH/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"ចូលទៅបណ្ដាញ"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml
index 0c80547..af7eeaf 100644
--- a/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-kn-rIN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
index 670ace2..c6c5239 100644
--- a/packages/CaptivePortalLogin/res/values-ko/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ko/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"현재 상태로 이 네트워크 사용"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"네트워크에 로그인"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml b/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml
index a261c25..c77e47c 100644
--- a/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ky-rKG/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Тармакка кирүү"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
index c5e9177..7ed7c5f 100644
--- a/packages/CaptivePortalLogin/res/values-lt/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-lt/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Naudoti šį tinklą tokį, koks yra"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Prisijungti prie tinklo"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
index 6e43fc0..bb8b00b 100644
--- a/packages/CaptivePortalLogin/res/values-lv/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-lv/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Pierakstīties tīklā"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-mk-rMK/strings.xml b/packages/CaptivePortalLogin/res/values-mk-rMK/strings.xml
index dd8d78f..db0dd17 100644
--- a/packages/CaptivePortalLogin/res/values-mk-rMK/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mk-rMK/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Користи ја мрежата во оваа состојба"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Најавете се на мрежа"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml
index 7e7bcb3..bd1ac2d3 100644
--- a/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ml-rIN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml b/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml
index 78389ca..ad9f68b 100644
--- a/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mn-rMN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Энэ сүлжээг ашиглана уу"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Сүлжээнд нэвтэрнэ үү"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml
index fab7413..6ed7679 100644
--- a/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mr-rIN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"हे नेटवर्क जसेच्या तसे वापरा"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
index 70441f1..9e2664f 100644
--- a/packages/CaptivePortalLogin/res/values-nb/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-nb/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Bruk dette nettverket som det er"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Logg på nettverk"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
index 0a76ef1..e4ecb00 100644
--- a/packages/CaptivePortalLogin/res/values-nl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-nl/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Dit netwerk in de huidige staat gebruiken"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Inloggen bij netwerk"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
index 960b5e8..479301c 100644
--- a/packages/CaptivePortalLogin/res/values-pl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pl/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Używaj tej sieci tak jak jest"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Zaloguj się do sieci"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
index df9a875..5cb1d76 100644
--- a/packages/CaptivePortalLogin/res/values-ru/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ru/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Использовать эту сеть"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Регистрация в сети"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml b/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml
index dd0dca4..66efc2e 100644
--- a/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-si-rLK/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"ජාලයට පුරනය වන්න"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
index aa5d306..e633970 100644
--- a/packages/CaptivePortalLogin/res/values-sl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sl/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Uporabljajte to omrežje, »kakršno je«"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Prijavite se v omrežje"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-sr/strings.xml b/packages/CaptivePortalLogin/res/values-sr/strings.xml
index 4e396af..67f3b05 100644
--- a/packages/CaptivePortalLogin/res/values-sr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sr/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Користи ову мрежу такву каква је"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Пријави ме на мрежу"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml
index c8d845c..b695c6c 100644
--- a/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ta-rIN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml
index 126058f..798b16d 100644
--- a/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-te-rIN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
index 42a11eb..b16e2c1 100644
--- a/packages/CaptivePortalLogin/res/values-tl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-tl/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Gamitin ang network na ito nang walang pagbabago"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Huwag gamitin ang network na ito"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Mag-sign in sa network"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-tr/strings.xml b/packages/CaptivePortalLogin/res/values-tr/strings.xml
index 77fed29..bd4d0ec 100644
--- a/packages/CaptivePortalLogin/res/values-tr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-tr/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Bu ağı olduğu gibi kullan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Ağda oturum açın"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml b/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml
index 7ad2110..a5ba5cb 100644
--- a/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ur-rPK/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"نیٹ ورک میں سائن ان کریں"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml b/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml
index 355faaf..11e9648 100644
--- a/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-uz-rUZ/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Tarmoqqa kirish"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
index 239fc7f..1a76ceb 100644
--- a/packages/CaptivePortalLogin/res/values-vi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-vi/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Sử dụng mạng này"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Không sử dụng mạng này"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"Đăng nhập vào mạng"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
index 1f649cc..4de18b7 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"直接使用此网络"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"登录到网络"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
index 12389b7..3d68c84 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"依照現況使用這個網絡"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"登入網絡"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
index 9b1a5f4..95a5639 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
@@ -4,6 +4,5 @@
     <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
     <string name="action_use_network" msgid="6076184727448466030">"依現況使用這個網路"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
-    <!-- no translation found for action_bar_label (917235635415966620) -->
-    <skip />
+    <string name="action_bar_label" msgid="917235635415966620">"登入網路"</string>
 </resources>
diff --git a/packages/DefaultContainerService/res/values-en-rAU/strings.xml b/packages/DefaultContainerService/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..2bd5615
--- /dev/null
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Open from"</string>
+    <string name="title_save" msgid="2433679664882857999">"Save to"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
+    <string name="menu_list" msgid="7279285939892417279">"List view"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Search"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Settings"</string>
+    <string name="menu_open" msgid="432922957274920903">"Open"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Save"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Share"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+    <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
+    <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
+    <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
+    <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
+    <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Hide SD card"</string>
+    <string name="menu_file_size_show" msgid="3240323619260823076">"Show file size"</string>
+    <string name="menu_file_size_hide" msgid="8881975928502581042">"Hide file size"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+    <string name="sort_name" msgid="9183560467917256779">"By name"</string>
+    <string name="sort_date" msgid="586080032956151448">"By date modified"</string>
+    <string name="sort_size" msgid="3350681319735474741">"By size"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Show roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
+    <string name="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Shortcuts"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
+    <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
+    <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..f88eb9e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-en-rAU/strings.xml b/packages/FusedLocation/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-en-rAU/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..d5797a0
--- /dev/null
+++ b/packages/InputDevices/res/values-en-rAU/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android keyboard"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), International style"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), Colemak style"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), Dvorak style"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russian"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, Mac style"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Swiss French"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Swiss German"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgian"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarian"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croatian"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonian"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilian"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainian"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabic"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greek"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrew"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lithuanian"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanish (Latin)"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latvian"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-en-rAU/strings.xml b/packages/Keyguard/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ee5da13
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rAU/strings.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="719438068451601849">"Keyguard"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"Type SIM PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"New SIM PIN code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
+    <string name="keyguard_plugged_in" msgid="9087497435553252863">"Charging"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"No SIM card"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No SIM card in tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No SIM card in phone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insert a SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"The SIM card is missing or not readable. Insert a SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Unusable SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM card is locked."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM card is PUK-locked."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Unlocking SIM card…"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+    <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>
+    <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_next_alarm" msgid="7269583073750518672">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact operator for details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK code should be 8 numbers or more."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
+    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
+      <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
+      <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your operator to unlock your device.</item>
+    </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM is unusable. Contact your operator."</string>
+    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
+      <item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
+      <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
+    </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN operation failed!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK operation failed!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code accepted"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
+</resources>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..e5721b2
--- /dev/null
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4469836075319831821">"Print Spooler"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"More options"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+    <string name="label_copies_summary" msgid="3861966063536529540">"Copies:"</string>
+    <string name="label_paper_size" msgid="908654383827777759">"Paper size"</string>
+    <string name="label_paper_size_summary" msgid="5668204981332138168">"Paper size:"</string>
+    <string name="label_color" msgid="1108690305218188969">"Colour"</string>
+    <string name="label_duplex" msgid="1263181386446435253">"Duplex"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+    <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="template_all_pages" msgid="3322235982020148762">"All <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+    <string name="template_page_range" msgid="428638530038286328">"Range of <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Print preview"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Install PDF viewer for preview"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Printing app crashed"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generating print job"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Save as PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"All printers…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Print dialogue"</string>
+    <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="page_description_template" msgid="6831239682256197161">"Page <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> of <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"Summary, copies <xliff:g id="COPIES">%1$s</xliff:g>, paper size <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"Expand handle"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"Collapse handle"</string>
+    <string name="print_button" msgid="645164566271246268">"Print"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"Save to PDF"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"Print options expanded"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"Print options collapsed"</string>
+    <string name="search" msgid="5421724265322228497">"Search"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"All printers"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Add service"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Search box shown"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Search box hidden"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Add printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Select printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Forget printer"</string>
+    <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> printer found</item>
+    </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer blocked <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <plurals name="composite_notification_title_template" formatted="false" msgid="6940956968211733780">
+      <item quantity="other"><xliff:g id="PRINT_JOB_NAME_1">%1$d</xliff:g> print jobs</item>
+      <item quantity="one"><xliff:g id="PRINT_JOB_NAME_0">%1$d</xliff:g> print job</item>
+    </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancel"</string>
+    <string name="restart" msgid="2472034227037808749">"Restart"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Black &amp; White"</item>
+    <item msgid="2762241247228983754">"Colour"</item>
+  </string-array>
+  <string-array name="duplex_mode_labels">
+    <item msgid="3882302912790928315">"None"</item>
+    <item msgid="7296563835355641719">"Long edge"</item>
+    <item msgid="79513688117503758">"Short edge"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Landscape"</item>
+  </string-array>
+    <string name="print_write_error_message" msgid="5787642615179572543">"Couldn\'t write to file"</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
+    <string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
+    <string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+    <string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-en-rAU/defaults.xml b/packages/SettingsProvider/res/values-en-rAU/defaults.xml
new file mode 100644
index 0000000..22443a5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-en-rAU/defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+    <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-en-rAU/strings.xml b/packages/SettingsProvider/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..c19fdd7
--- /dev/null
+++ b/packages/SettingsProvider/res/values-en-rAU/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Settings Storage"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 30786f0..952b220 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -62,9 +62,10 @@
      */
     private static final ArraySet<String> sBroadcastOnRestore;
     static {
-        sBroadcastOnRestore = new ArraySet<String>(2);
+        sBroadcastOnRestore = new ArraySet<String>(3);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        sBroadcastOnRestore.add(Settings.Secure.ENABLED_INPUT_METHODS);
     }
 
     private interface SettingsLookup {
diff --git a/packages/Shell/res/values-en-rAU/strings.xml b/packages/Shell/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..fab4223
--- /dev/null
+++ b/packages/Shell/res/values-en-rAU/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string>
+    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
+</resources>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 158e133..7a58c87 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -106,6 +106,9 @@
     <uses-permission android:name="android.permission.TRUST_LISTENER" />
     <uses-permission android:name="android.permission.USE_FINGERPRINT" />
 
+    <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
+    <uses-permission android:name="android.permission.SET_WALLPAPER"/>
+
     <!-- Recents -->
     <uses-permission android:name="android.permission.BIND_APPWIDGET" />
 
diff --git a/packages/SystemUI/res/drawable/vector_drawable_place_bottom.xml b/packages/SystemUI/res/drawable/vector_drawable_place_bottom.xml
new file mode 100644
index 0000000..14f1981
--- /dev/null
+++ b/packages/SystemUI/res/drawable/vector_drawable_place_bottom.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M0.0,0.0l0.0,24.0l24.0,0.0L24.0,0.0L0.0,0.0zM4.0,10.0l16.0,0.0l0.0,10.0L4.0,20.0L4.0,10.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/vector_drawable_place_fullscreen.xml b/packages/SystemUI/res/drawable/vector_drawable_place_fullscreen.xml
new file mode 100644
index 0000000..aee0b7f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/vector_drawable_place_fullscreen.xml
@@ -0,0 +1,33 @@
+<!--
+Copyright (C) 2015 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:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M0.0,8.0l4.0,0.0 0.0,-4.0 4.0,0.0 0.0,-4.0 -8.0,0.0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M4.0,16.0l-4.0,0.0 0.0,8.0 8.0,0.0 0.0,-4.0 -4.0,0.0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16.0,0.0l0.0,4.0 4.0,0.0 0.0,4.0 4.0,0.0 0.0,-8.0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M20.0,20.0l-4.0,0.0 0.0,4.0 8.0,0.0 0.0,-8.0 -4.0,0.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/vector_drawable_place_left.xml b/packages/SystemUI/res/drawable/vector_drawable_place_left.xml
new file mode 100644
index 0000000..078f83c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/vector_drawable_place_left.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M24.0,0.0L0.0,0.0l0.0,24.0l24.0,0.0L24.0,0.0zM14.0,4.0l0.0,16.0L4.0,20.0L4.0,4.0L14.0,4.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/vector_drawable_place_right.xml b/packages/SystemUI/res/drawable/vector_drawable_place_right.xml
new file mode 100644
index 0000000..86730db
--- /dev/null
+++ b/packages/SystemUI/res/drawable/vector_drawable_place_right.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M0.0,24.0l24.0,0.0L24.0,0.0L0.0,0.0L0.0,24.0zM10.0,20.0L10.0,4.0l10.0,0.0l0.0,16.0L10.0,20.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/vector_drawable_place_top.xml b/packages/SystemUI/res/drawable/vector_drawable_place_top.xml
new file mode 100644
index 0000000..92e01af
--- /dev/null
+++ b/packages/SystemUI/res/drawable/vector_drawable_place_top.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M24.0,24.0L24.0,0.0L0.0,0.0l0.0,24.0L24.0,24.0zM20.0,14.0L4.0,14.0L4.0,4.0l16.0,0.0L20.0,14.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml b/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml
deleted file mode 100644
index 36e54a0..0000000
--- a/packages/SystemUI/res/layout/recents_multistack_stack_size_dialog.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:padding="16dp"
-    android:orientation="vertical"
-    android:descendantFocusability="beforeDescendants"
-    android:focusableInTouchMode="true">
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal">
-        <EditText
-            android:id="@+id/inset_left"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="Left"
-            android:singleLine="true"
-            android:imeOptions="actionNext"
-            android:inputType="number"
-            android:selectAllOnFocus="true" />
-        <EditText
-            android:id="@+id/inset_top"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="Top"
-            android:singleLine="true"
-            android:imeOptions="actionNext"
-            android:inputType="number"
-            android:selectAllOnFocus="true" />
-        <EditText
-            android:id="@+id/inset_right"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="Right"
-            android:singleLine="true"
-            android:imeOptions="actionNext"
-            android:inputType="number"
-            android:selectAllOnFocus="true" />
-        <EditText
-            android:id="@+id/inset_bottom"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:hint="Bottom"
-            android:singleLine="true"
-            android:imeOptions="actionDone"
-            android:inputType="number"
-            android:selectAllOnFocus="true" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_task_resize_dialog.xml b/packages/SystemUI/res/layout/recents_task_resize_dialog.xml
new file mode 100644
index 0000000..a8c6ee9
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_task_resize_dialog.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="16dp"
+    android:orientation="vertical"
+    android:descendantFocusability="beforeDescendants"
+    android:focusableInTouchMode="true">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <Button
+            android:id="@+id/place_left"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_weight="1"
+            android:layout_margin="10dp"
+            android:background="@drawable/vector_drawable_place_left" />
+        <Button
+            android:id="@+id/place_right"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_weight="1"
+            android:layout_margin="10dp"
+            android:background="@drawable/vector_drawable_place_right" />
+        <Button
+            android:id="@+id/place_top"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_weight="1"
+            android:layout_margin="10dp"
+            android:background="@drawable/vector_drawable_place_top" />
+        <Button
+            android:id="@+id/place_bottom"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_weight="1"
+            android:layout_margin="10dp"
+            android:background="@drawable/vector_drawable_place_bottom" />
+        <Button
+            android:id="@+id/place_full"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:layout_weight="1"
+            android:layout_margin="10dp"
+            android:background="@drawable/vector_drawable_place_fullscreen" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 34e4beb..d234701 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Geen netwerk nie"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi af"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Geen gestoorde netwerke beskikbaar nie"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Saai uit"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Saai tans uit"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Onbenoemde toestel"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Gereed om uit te saai"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 104067a..2bcb2c1 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -261,8 +261,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"لا تتوفر شبكة"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏إيقاف Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"لا تتوفر أية شبكة محفوظة"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"إرسال"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"جارٍ الإرسال"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"جهاز لا يحمل اسمًا"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"جاهز للإرسال"</string>
diff --git a/packages/SystemUI/res/values-en-rAU-land/strings.xml b/packages/SystemUI/res/values-en-rAU-land/strings.xml
new file mode 100644
index 0000000..ba773b8
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rAU-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="toast_rotation_locked" msgid="7609673011431556092">"Screen is now locked in landscape orientation."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ee3f826
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"System UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Clear"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remove from list"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App info"</string>
+    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Your recent screens appear here"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dismiss recent apps"</string>
+    <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
+      <item quantity="other">%d screens in Overview</item>
+      <item quantity="one">1 screen in Overview</item>
+    </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No notifications"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Ongoing"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Battery is low"</string>
+    <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining. Battery saver is on."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported.\nUse only the supplied charger."</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB charging not supported."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Use only the supplied charger."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Settings"</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Turn on battery saver?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Turn on"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"Turn on battery saver"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Settings"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Aeroplane mode"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Auto-rotate screen"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB accessory is connected?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"No installed apps work with this USB accessory. Learn more about this accessory at <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string>
+    <string name="label_view" msgid="6304565553218192990">"View"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Allow USB debugging?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"The computer\'s RSA key fingerprint is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Always allow from this computer"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Zoom to fill screen"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Stretch to fill screen"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Saving screenshot…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Saving screenshot…"</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot is being saved."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+    <string name="screenshot_failed_text" msgid="1260203058661337274">"Can\'t take screenshot due to limited storage space, or it isn\'t allowed by the app or your organisation."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Install Android File Transfer application for Mac"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Back"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"Overview"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Search"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
+    <string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string>
+    <string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string>
+    <string name="unlock_label" msgid="8779712358041029439">"unlock"</string>
+    <string name="phone_label" msgid="2320074140205331708">"open phone"</string>
+    <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth disconnected."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"No battery."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Battery one bar."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Battery two bars."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Battery three bars."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Battery full."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"No phone."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Phone one bar."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Phone two bars."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Phone three bars."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Phone signal full."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"No data."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data one bar."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data two bars."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data three bars."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data signal full."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wi-Fi off."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wi-Fi disconnected."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wi-Fi one bar."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wi-Fi two bars."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wi-Fi three bars."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wi-Fi signal full."</string>
+    <string name="accessibility_wifi_name" msgid="7202151365171148501">"Connected to <xliff:g id="WIFI">%s</xliff:g>."</string>
+    <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"No WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX one bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX two bars."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX three bars."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signal full."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"No signal."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Not connected."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Zero bars."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"One bar."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Two bars."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Three bars."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Signal full."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"On."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Off."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Connected."</string>
+    <string name="accessibility_desc_connecting" msgid="3812924520316280149">"Connecting."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string>
+    <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"No SIM."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Aeroplane mode"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Clear notification."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS enabled."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS acquiring."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter enabled."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringer vibrate."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
+    <!-- no translation found for accessibility_casting (6887382141726543668) -->
+    <skip />
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
+    <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
+    <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Lock screen."</string>
+    <string name="accessibility_desc_settings" msgid="3417884241751434521">"Settings"</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Overview."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi turned off."</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wi-Fi turned on."</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Battery <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Aeroplane mode off."</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Aeroplane mode on."</string>
+    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Aeroplane mode turned off."</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Aeroplane mode turned on."</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\'Do not disturb\' on, priority only."</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="5910777408232088752">"\'Do not disturb\' on, no interruptions."</string>
+    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\'Do not disturb\' off."</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\'Do not disturb\' turned off."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\'Do not disturb\' turned on."</string>
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth off."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth on."</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Bluetooth connecting."</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth connected."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"Bluetooth turned off."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"Bluetooth turned on."</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Location reporting off."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Location reporting on."</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"Location reporting turned off."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"Location reporting turned on."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Close panel."</string>
+    <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"More time."</string>
+    <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"Less time."</string>
+    <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Torch off."</string>
+    <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Torch on."</string>
+    <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Torch turned off."</string>
+    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Torch turned on."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Colour inversion turned off."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Colour inversion turned on."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot turned off."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot turned on."</string>
+    <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Screen casting stopped."</string>
+    <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobile data is paused"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Data is paused"</string>
+    <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Because your set data limit was reached, the device has paused data usage for the remainder of this cycle.\n\nResuming may lead to charges from your operator."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Resume"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No Internet connection"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connected"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Searching for GPS"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Screen will now rotate automatically."</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Screen is now locked in landscape orientation."</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Screen is now locked in portrait orientation."</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Aeroplane mode"</string>
+    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
+    <string name="quick_settings_dnd_none_label" msgid="7309935569360609114">"No interruptions"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> Devices)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Off"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"No paired devices available"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brightness"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Auto-rotate"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotation locked"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Landscape"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Input Method"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Location"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Location Off"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media device"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Emergency Calls Only"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Settings"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Time"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Me"</string>
+    <string name="quick_settings_user_title" msgid="4467690427642392403">"User"</string>
+    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"New user"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Not Connected"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No Network"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"No saved networks available"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
+    <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
+    <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colours"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+    <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
+    <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
+    <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
+    <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">"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>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Over limit"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> used"</string>
+    <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string>
+    <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
+    <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Dismiss all applications"</string>
+    <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
+    <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
+    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
+    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string>
+    <string name="expanded_header_battery_charging" msgid="205623198487189724">"Charging"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> until full"</string>
+    <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Not charging"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"No interruptions. Not even alarms."</string>
+    <string name="zen_no_interruptions" msgid="7970973750143632592">"No interruptions"</string>
+    <string name="zen_important_interruptions" msgid="3477041776609757628">"Priority interruptions only"</string>
+    <string name="zen_alarm_information_time" msgid="5235772206174372272">"Your next alarm is at <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+    <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Your next alarm is <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
+    <string name="zen_alarm_warning" msgid="6873910860111498041">"You won\'t hear your alarm at <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
+    <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
+    <string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string>
+    <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
+    <string name="phone_hint" msgid="3101468054914424646">"Swipe right for phone"</string>
+    <string name="camera_hint" msgid="5241441720959174226">"Swipe left for camera"</string>
+    <string name="interruption_level_none" msgid="3831278883136066646">"None"</string>
+    <string name="interruption_level_priority" msgid="6517366750688942030">"Priority"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Show profile"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"Add user"</string>
+    <string name="user_new_user_name" msgid="426540612051178753">"New user"</string>
+    <string name="guest_nickname" msgid="8059989128963789678">"Guest"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"Add guest"</string>
+    <string name="guest_exit_guest" msgid="7187359342030096885">"Remove guest"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Remove guest?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"All apps and data in this session will be deleted."</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Remove"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Welcome back, guest!"</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Do you want to continue your session?"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Start again"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Yes, continue"</string>
+    <string name="user_add_user_title" msgid="4553596395824132638">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduces performance and background data"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Turn off battery saver"</string>
+    <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
+    <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
+    <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
+    <string name="device_owned_footer" msgid="3802752663326030053">"Device may be monitored"</string>
+    <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"Network may be monitored"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Device monitoring"</string>
+    <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Profile monitoring"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"Network monitoring"</string>
+    <string name="disable_vpn" msgid="4435534311510272506">"Disable VPN"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"Disconnect VPN"</string>
+    <string name="monitoring_description_device_owned" msgid="7512371572956715493">"This device is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator."</string>
+    <string name="monitoring_description_vpn" msgid="7288268682714305659">"You gave \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites."</string>
+    <string name="monitoring_description_legacy_vpn" msgid="4740349017929725435">"You\'re connected to a VPN (\"<xliff:g id="APPLICATION">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your device and network activity including emails, apps and secure websites."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"This device is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too."</string>
+    <string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"This device is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too."</string>
+    <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"This profile is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator."</string>
+    <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"This device is managed by:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"This profile is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too."</string>
+    <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"This profile is managed by:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too."</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"This device is managed by:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="APPLICATION">%3$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too."</string>
+    <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"This device is managed by:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="APPLICATION">%3$s</xliff:g>\"). Your VPN service provider can monitor network activity too."</string>
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
+    <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, thanks"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Setup"</string>
+    <string name="notification_expand_button_text" msgid="1037425494153780718">"See all"</string>
+    <string name="notification_collapse_button_text" msgid="6883253262134328057">"Hide all"</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">"Screen is pinned"</string>
+    <string name="screen_pinning_description" msgid="1346522416878235405">"This keeps it in view until you unpin. Touch and hold Back and Overview at the same time to unpin."</string>
+    <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"This keeps it in view until you unpin. Touch and hold Overview to unpin."</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
+    <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
+    <string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> wants to be the volume dialogue."</string>
+    <string name="volumeui_prompt_allow" msgid="7954396902482228786">"Allow"</string>
+    <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
+    <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
+    <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9ac2a64..ee3f826 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No Network"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"No saved networks available"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 9ac2a64..ee3f826 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No Network"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"No saved networks available"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 398e0b0..18d8f76 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"شبکه‌ای موجود نیست"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi خاموش است"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"شبکه ذخیره شده‌ای در دسترس نیست"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"فرستادن"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"در حال فرستادن"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"دستگاه بدون نام"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"آماده برای فرستادن"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 66a7df0..5bf8d13 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Tidak Ada Jaringan"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Mati"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Jaringan yang tersimpan tak tersedia"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmisi"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Melakukan transmisi"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Perangkat tanpa nama"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Siap melakukan transmisi"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index b5e1bfe..6ae0c71 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ບໍ່ມີເຄືອຂ່າຍ"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi​-Fi ປິດ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"ບໍ່​ມີ​ເຄືອ​ຂ່າຍ​ທີ່​ບັນ​ທຶກ​ໄວ້​ທີ່​ສາ​ມາດ​ໃຊ້​ໄດ້"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ຄາສທ໌"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"​ກຳ​ລັງ​ສົ່ງ​ສັນ​ຍານ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"​ອຸ​ປະ​ກອນບໍ່​ມີ​ຊື່"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"​ພ້ອ​ມ​ສົ່ງ​ສັນ​ຍານ​ແລ້ວ"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index a767983..f7268c2 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -255,8 +255,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Сүлжээгүй"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi унтарсан"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Хадгалагдсан сүлжээ байхгүй"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Дамжуулах"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Дамжуулж байна"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Нэргүй төхөөрөмж"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Дамжуулахад бэлэн"</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index b6feaa2..58e5239 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ကွန်ရက်မရှိပါ"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ဝိုင်ဖိုင်ပိတ်ရန်"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"သိမ်းဆည်းထား ကွန်ရက်များ မရှိ"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ကာစ်တင်"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"အမည်မတပ် ကိရိယာ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 71247d9..3d5d213 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"नेटवर्क छैन"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाइफाइ बन्द"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"उपलब्ध सञ्जाल सुरक्षित गरिएन"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"प्रसारण गर्दै"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"बेनाम उपकरण"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"प्रसारण गर्न तयार"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index becf69d..ef864de 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ජාලයක් නැත"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi අක්‍රියයි"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"තිබෙන ජාල සුරැකුවේ නැත"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"කාස්ට් කිරීම"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"නම් නොකළ උපාංගය"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"කාස්ට් කිරීමට සුදානම්"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 493c9e7..f60a85a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -257,8 +257,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Walang Network"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Naka-off ang Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"Walang available na naka-save na mga network"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"I-cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Nagka-cast"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Walang pangalang device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Handang mag-cast"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 78eadee..6636693 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -259,8 +259,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"沒有網絡"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 關閉"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="2831702993995222755">"找不到已儲存的網絡"</string>
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"投放"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"正在放送"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名的裝置"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"放送準備完成"</string>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 66d494b..b696787 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -216,6 +216,10 @@
     <string name="phone_label">open phone</string>
     <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
     <string name="camera_label">open camera</string>
+    <!-- Caption for "Recents resize" developer debug feature. [CHAR LIMIT=NONE] -->
+    <string name="recents_caption_resize">Select new task layout</string>
+    <!-- Button name for "Cancel". [CHAR LIMIT=NONE] -->
+    <string name="cancel">Cancel</string>
 
     <!-- Content description of the compatibility zoom button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_compatibility_zoom_button">Compatibility zoom button.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 9dd82fc..2d1fab0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -42,6 +42,7 @@
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.misc.Console;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
@@ -53,6 +54,7 @@
 import com.android.systemui.recents.views.TaskStackViewLayoutAlgorithm;
 import com.android.systemui.recents.views.TaskViewHeader;
 import com.android.systemui.recents.views.TaskViewTransform;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -79,6 +81,8 @@
     // Owner proxy events
     final public static String ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER =
             "action_notify_recents_visibility_change";
+    final public static String ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER =
+            "action_screen_pinning_request";
 
     final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
     final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
@@ -148,6 +152,9 @@
                 case ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER:
                     visibilityChanged(intent.getBooleanExtra(EXTRA_RECENTS_VISIBILITY, false));
                     break;
+                case ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER:
+                    onStartScreenPinning(context);
+                    break;
             }
         }
     }
@@ -234,6 +241,7 @@
             mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver();
             IntentFilter filter = new IntentFilter();
             filter.addAction(Recents.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
+            filter.addAction(Recents.ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER);
             mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter,
                     null, mHandler);
         }
@@ -377,7 +385,7 @@
         }
 
         // Return early if there are no tasks in the focused stack
-        if (focusedStack.getTaskCount() == 0) return;
+        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
 
         ActivityManager.RunningTaskInfo runningTask = mSystemServicesProxy.getTopMostTask();
         // Return early if there is no running task (can't determine affiliated tasks in this case)
@@ -801,6 +809,27 @@
         }
     }
 
+    /** Notifies the status bar to trigger screen pinning. */
+    @ProxyFromAnyToPrimaryUser
+    public static void startScreenPinning(Context context, SystemServicesProxy ssp) {
+        if (ssp.isForegroundUserOwner()) {
+            onStartScreenPinning(context);
+        } else {
+            Intent intent = createLocalBroadcastIntent(context,
+                    ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER);
+            context.sendBroadcastAsUser(intent, UserHandle.OWNER);
+        }
+    }
+    static void onStartScreenPinning(Context context) {
+        // For the primary user, the context for the SystemUI component is the SystemUIApplication
+        SystemUIApplication app = (SystemUIApplication)
+                getInstanceAndStartIfNeeded(context).mContext;
+        PhoneStatusBar statusBar = app.getComponent(PhoneStatusBar.class);
+        if (statusBar != null) {
+            statusBar.showScreenPinningRequest(false);
+        }
+    }
+
     /**
      * Returns the preloaded load plan and invalidates it.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1248672..f014f09 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -85,8 +85,6 @@
     // Runnables to finish the Recents activity
     FinishRecentsRunnable mFinishLaunchHomeRunnable;
 
-    private PhoneStatusBar mStatusBar;
-
     /**
      * A common Runnable to finish Recents either by calling finish() (with a custom animation) or
      * launching Home with some ActivityOptions.  Generally we always launch home when we exit
@@ -381,8 +379,6 @@
         mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
         mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub);
         mScrimViews = new SystemBarScrimViews(this, mConfig);
-        mStatusBar = ((SystemUIApplication) getApplication())
-                .getComponent(PhoneStatusBar.class);
         inflateDebugOverlay();
 
         // Bind the search app widget when we first start up
@@ -596,14 +592,14 @@
 
     private RecentsResizeTaskDialog getResizeTaskDebugDialog() {
         if (mResizeTaskDebugDialog == null) {
-            mResizeTaskDebugDialog = new RecentsResizeTaskDialog(getFragmentManager());
+            mResizeTaskDebugDialog = new RecentsResizeTaskDialog(getFragmentManager(), this);
         }
         return mResizeTaskDebugDialog;
     }
 
     @Override
     public void onTaskResize(Task t) {
-        getResizeTaskDebugDialog().showResizeTaskDialog(t);
+        getResizeTaskDebugDialog().showResizeTaskDialog(t, mRecentsView);
     }
 
     /**** RecentsView.RecentsViewCallbacks Implementation ****/
@@ -631,9 +627,9 @@
 
     @Override
     public void onScreenPinningRequest() {
-        if (mStatusBar != null) {
-            mStatusBar.showScreenPinningRequest(false);
-        }
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        SystemServicesProxy ssp = loader.getSystemServicesProxy();
+        Recents.startScreenPinning(this, ssp);
     }
 
     /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 9263543..abeb2b0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -292,7 +292,7 @@
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED) != 0;
         lockToAppEnabled = ssp.getSystemSetting(context,
                 Settings.System.LOCK_TO_APP_ENABLED) != 0;
-        multiStackEnabled = "1".equals(ssp.getSystemProperty("overview.enableMultiStack"));
+        multiStackEnabled = "true".equals(ssp.getSystemProperty("persist.sys.debug.multi_window"));
     }
 
     /** Called when the configuration has changed, and we want to reset any configuration specific
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
index d67eceb..7c11894 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
@@ -16,31 +16,23 @@
 
 package com.android.systemui.recents;
 
-import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.FragmentManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ResolveInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.util.MutableInt;
-import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.EditText;
-import android.widget.Toast;
+import android.widget.Button;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
-
-import java.util.List;
+import com.android.systemui.recents.RecentsActivity;
+import com.android.systemui.recents.views.RecentsView;
 
 /**
  * A helper for the dialogs that show when task debugging is on.
@@ -49,80 +41,137 @@
 
     static final String TAG = "RecentsResizeTaskDialog";
 
+    // The various window arrangements we can handle.
+    private static final int PLACE_LEFT = 1;
+    private static final int PLACE_RIGHT = 2;
+    private static final int PLACE_TOP = 3;
+    private static final int PLACE_BOTTOM = 4;
+    private static final int PLACE_FULL = 5;
+
     // The task we want to resize.
-    Task mTaskToResize;
-    FragmentManager mFragmentManager;
-    View mResizeTaskDialogContent;
+    private Task mTaskToResize;
+    private Task mNextTaskToResize;
+    private FragmentManager mFragmentManager;
+    private View mResizeTaskDialogContent;
+    private RecentsActivity mRecentsActivity;
+    private RecentsView mRecentsView;
+    private SystemServicesProxy mSsp;
 
-    public RecentsResizeTaskDialog() {}
-
-    public RecentsResizeTaskDialog(FragmentManager mgr) {
+    public RecentsResizeTaskDialog(FragmentManager mgr, RecentsActivity activity) {
         mFragmentManager = mgr;
+        mRecentsActivity = activity;
+        mSsp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
     }
 
     /** Shows the resize-task dialog. */
-    void showResizeTaskDialog(Task t) {
-        mTaskToResize = t;
+    void showResizeTaskDialog(Task mainTask, RecentsView rv) {
+        mTaskToResize = mainTask;
+        mRecentsView = rv;
+        mNextTaskToResize = mRecentsView.getNextTaskOrTopTask(mainTask);
+
         show(mFragmentManager, TAG);
     }
 
     /** Creates a new resize-task dialog. */
     private void createResizeTaskDialog(final Context context, LayoutInflater inflater,
-            AlertDialog.Builder builder, final SystemServicesProxy ssp) {
-        builder.setTitle("Resize Task - Enter new dimensions");
+            AlertDialog.Builder builder) {
+        builder.setTitle(R.string.recents_caption_resize);
         mResizeTaskDialogContent =
-                inflater.inflate(R.layout.recents_multistack_stack_size_dialog, null, false);
-        Rect bounds = ssp.getTaskBounds(mTaskToResize.key.stackId);
-        setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_left, bounds.left);
-        setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_top, bounds.top);
-        setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_right, bounds.right);
-        setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_bottom, bounds.bottom);
+                inflater.inflate(R.layout.recents_task_resize_dialog, null, false);
+
+        ((Button)mResizeTaskDialogContent.findViewById(R.id.place_left)).setOnClickListener(
+                new View.OnClickListener() {
+            public void onClick(View v) {
+                placeTasks(PLACE_LEFT);
+            }
+        });
+        ((Button)mResizeTaskDialogContent.findViewById(R.id.place_right)).setOnClickListener(
+                new View.OnClickListener() {
+            public void onClick(View v) {
+                placeTasks(PLACE_RIGHT);
+            }
+        });
+        ((Button)mResizeTaskDialogContent.findViewById(R.id.place_top)).setOnClickListener(
+                new View.OnClickListener() {
+            public void onClick(View v) {
+                placeTasks(PLACE_TOP);
+            }
+        });
+        ((Button)mResizeTaskDialogContent.findViewById(R.id.place_bottom)).setOnClickListener(
+                new View.OnClickListener() {
+            public void onClick(View v) {
+                placeTasks(PLACE_BOTTOM);
+            }
+        });
+        ((Button)mResizeTaskDialogContent.findViewById(R.id.place_full)).setOnClickListener(
+                new View.OnClickListener() {
+            public void onClick(View v) {
+                placeTasks(PLACE_FULL);
+            }
+        });
+
+        builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                dismiss();
+            }
+        });
+
         builder.setView(mResizeTaskDialogContent);
-        builder.setPositiveButton("Resize Task", new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                int left = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_left);
-                int top = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_top);
-                int right = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_right);
-                int bottom = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_bottom);
-                if (bottom <= top || right <= left) {
-                    Toast.makeText(context, "Invalid dimensions", Toast.LENGTH_SHORT).show();
-                    dismiss();
-                    return;
-                }
-                ssp.resizeTask(mTaskToResize.key.id, new Rect(left, top, right, bottom));
-                dismiss();
-            }
-        });
-        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                dismiss();
-            }
-        });
     }
 
-    /** Helper to get an integer value from an edit text. */
-    private int getDimensionFromEditText(View container, int id) {
-        String text = ((EditText) container.findViewById(id)).getText().toString();
-        if (text.trim().length() != 0) {
-            return Integer.parseInt(text.trim());
+    /** Helper function to place window(s) on the display according to an arrangement request. */
+    private void placeTasks(int arrangement) {
+        Rect focusedBounds = mSsp.getWindowRect();
+        Rect otherBounds = new Rect(focusedBounds);
+
+        switch (arrangement) {
+            case PLACE_LEFT:
+                focusedBounds.right = focusedBounds.centerX();
+                otherBounds.left = focusedBounds.right;
+                break;
+            case PLACE_RIGHT:
+                otherBounds.right = otherBounds.centerX();
+                focusedBounds.left = otherBounds.right;
+                break;
+            case PLACE_TOP:
+                focusedBounds.bottom = focusedBounds.centerY();
+                otherBounds.top = focusedBounds.bottom;
+                break;
+            case PLACE_BOTTOM:
+                otherBounds.bottom = otherBounds.centerY();
+                focusedBounds.top = otherBounds.bottom;
+                break;
+            case PLACE_FULL:
+                // Null the rectangle to avoid the other task to show up.
+                otherBounds = new Rect();
+                break;
         }
-        return 0;
-    }
 
-    /** Helper to set an integer value to an edit text. */
-    private void setDimensionInEditText(View container, int id, int value) {
-        ((EditText) container.findViewById(id)).setText("" + value);
+        // Resize all other tasks to go to the other side.
+        if (mNextTaskToResize != null && !otherBounds.isEmpty()) {
+            mSsp.resizeTask(mNextTaskToResize.key.id, otherBounds);
+        }
+        mSsp.resizeTask(mTaskToResize.key.id, focusedBounds);
+
+        // Get rid of the dialog.
+        dismiss();
+        mRecentsActivity.dismissRecentsToHomeRaw(false);
+
+        // Show tasks - beginning with the other first so that the focus ends on the selected one.
+        // TODO: Remove this once issue b/19893373 is resolved.
+        if (mNextTaskToResize != null && !otherBounds.isEmpty()) {
+            mRecentsView.launchTask(mNextTaskToResize);
+        }
+        mRecentsView.launchTask(mTaskToResize);
     }
 
     @Override
     public Dialog onCreateDialog(Bundle args) {
         final Context context = this.getActivity();
-        final SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
         LayoutInflater inflater = getActivity().getLayoutInflater();
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        createResizeTaskDialog(context, inflater, builder, ssp);
+        createResizeTaskDialog(context, inflater, builder);
         return builder.create();
     }
 }
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 a473a29..d60df9c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -259,7 +259,7 @@
     public Rect getTaskBounds(int stackId) {
         ActivityManager.StackInfo info = getAllStackInfos().get(stackId);
         if (info != null)
-          return getAllStackInfos().get(stackId).bounds;
+          return info.bounds;
         return new Rect();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 448a7a9..abed7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -149,6 +149,31 @@
         return mTaskStackViews;
     }
 
+    /** Gets the next task in the stack - or if the last - the top task */
+    public Task getNextTaskOrTopTask(Task taskToSearch) {
+        Task returnTask = null; 
+        boolean found = false;
+        List<TaskStackView> stackViews = getTaskStackViews();
+        int stackCount = stackViews.size();
+        for (int i = stackCount - 1; i >= 0; --i) {
+            TaskStack stack = stackViews.get(i).getStack();
+            ArrayList<Task> taskList = stack.getTasks();
+            // Iterate the stack views and try and find the focused task
+            for (int j = taskList.size() - 1; j >= 0; --j) {
+                Task task = taskList.get(j);
+                // Return the next task in the line.
+                if (found)
+                    return task;
+                // Remember the first possible task as the top task.
+                if (returnTask == null)
+                    returnTask = task;
+                if (task == taskToSearch)
+                    found = true;
+            }
+        }
+        return returnTask;
+    }
+
     /** Launches the focused task from the first stack if possible */
     public boolean launchFocusedTask() {
         // Get the first stack view
@@ -172,6 +197,28 @@
         return false;
     }
 
+    /** Launches a given task. */
+    public boolean launchTask(Task task) {
+        // Get the first stack view
+        List<TaskStackView> stackViews = getTaskStackViews();
+        int stackCount = stackViews.size();
+        for (int i = 0; i < stackCount; i++) {
+            TaskStackView stackView = stackViews.get(i);
+            TaskStack stack = stackView.getStack();
+            // Iterate the stack views and try and find the given task.
+            List<TaskView> taskViews = stackView.getTaskViews();
+            int taskViewCount = taskViews.size();
+            for (int j = 0; j < taskViewCount; j++) {
+                TaskView tv = taskViews.get(j);
+                if (tv.getTask() == task) {
+                    onTaskViewClicked(stackView, tv, stack, task, false);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     /** Launches the task that Recents was launched from, if possible */
     public boolean launchPreviousTask() {
         // Get the first stack view
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index ca08319..42399a3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -26,14 +26,15 @@
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.RippleDrawable;
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.PorterDuffXfermode;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.RippleDrawable;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
@@ -43,7 +44,9 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
+import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 
 
@@ -51,6 +54,7 @@
 public class TaskViewHeader extends FrameLayout {
 
     RecentsConfiguration mConfig;
+    private SystemServicesProxy mSsp;
 
     // Header views
     ImageView mMoveTaskButton;
@@ -91,6 +95,7 @@
     public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         mConfig = RecentsConfiguration.getInstance();
+        mSsp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
         setWillNotDraw(false);
         setClipToOutline(true);
         setOutlineProvider(new ViewOutlineProvider() {
@@ -124,9 +129,6 @@
         mActivityDescription = (TextView) findViewById(R.id.activity_description);
         mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
         mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
-        if (mConfig.multiStackEnabled) {
-            mMoveTaskButton.setVisibility(View.VISIBLE);
-        }
 
         // Hide the backgrounds if they are ripple drawables
         if (!Constants.DebugFlags.App.EnableTaskFiltering) {
@@ -209,6 +211,32 @@
                 mLightDismissDrawable : mDarkDismissDrawable);
         mDismissButton.setContentDescription(String.format(mDismissContentDescription,
                 t.activityLabel));
+        mMoveTaskButton.setVisibility((mConfig.multiStackEnabled) ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    /** Updates the resize task bar button. */
+    void updateResizeTaskBarIcon(Task t) {
+        Rect display = mSsp.getWindowRect();
+        Rect taskRect = mSsp.getTaskBounds(t.key.stackId);
+        int resId = R.drawable.star;
+        if (display.equals(taskRect)) {
+            resId = R.drawable.vector_drawable_place_fullscreen;
+        } else {
+            boolean top = display.top == taskRect.top;
+            boolean bottom = display.bottom == taskRect.bottom;
+            boolean left = display.left == taskRect.left;
+            boolean right = display.right == taskRect.right;
+            if (top && bottom && left) {
+                resId = R.drawable.vector_drawable_place_left;
+            } else if (top && bottom && right) {
+                resId = R.drawable.vector_drawable_place_right;
+            } else if (top && left && right) {
+                resId = R.drawable.vector_drawable_place_top;
+            } else if (bottom && left && right) {
+                resId = R.drawable.vector_drawable_place_bottom;
+            }
+        }
+        mMoveTaskButton.setImageResource(resId);
     }
 
     /** Unbinds the bar view from the task */
diff --git a/packages/VpnDialogs/res/values-en-rAU/strings.xml b/packages/VpnDialogs/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..2c93c78
--- /dev/null
+++ b/packages/VpnDialogs/res/values-en-rAU/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="3183836924226407828">"Connection request"</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wants to set up a VPN connection that allows it to monitor network traffic. Only accept if you trust the source. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; appears at the top of your screen when VPN is active."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN is connected"</string>
+    <string name="configure" msgid="4905518375574791375">"Configure"</string>
+    <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
+    <string name="session" msgid="6470628549473641030">"Session:"</string>
+    <string name="duration" msgid="3584782459928719435">"Duration:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Received:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+</resources>
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index 183726f..35d59dd 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -136,7 +136,7 @@
 
 
     /**
-     * @hide
+     *
      * Set the active X.  The x value must be within the range for
      * the allocation being adapted.
      *
@@ -208,7 +208,7 @@
     }
 
     /**
-     * @hide
+     *
      */
     public void setArray(int arrayNum, int arrayVal) {
         if (mAdaptedAllocation.getType().getArray(arrayNum) == 0) {
@@ -242,7 +242,7 @@
     }
 
     /**
-     * @hide
+     *
      *
      * Create an arbitrary window into the base allocation
      * The type describes the shape of the window.
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 8562288..e8e942c 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1351,7 +1351,7 @@
     }
 
     /**
-     * calls create(cts, ContextType.NORMAL, CREATE_FLAG_NONE)
+     * calls create(ctx, ContextType.NORMAL, CREATE_FLAG_NONE)
      *
      * See documentation for @create for details
      *
@@ -1363,7 +1363,7 @@
     }
 
     /**
-     * calls create(cts, ct, CREATE_FLAG_NONE)
+     * calls create(ctx, ct, CREATE_FLAG_NONE)
      *
      * See documentation for @create for details
      *
@@ -1375,7 +1375,8 @@
         return create(ctx, ct, CREATE_FLAG_NONE);
     }
 
-     /**
+
+    /**
      * Gets or creates a RenderScript context of the specified type.
      *
      * The returned context will be cached for future reuse within
@@ -1397,21 +1398,49 @@
      */
     public static RenderScript create(Context ctx, ContextType ct, int flags) {
         int v = ctx.getApplicationInfo().targetSdkVersion;
-        if (v < 23) {
-            return internalCreate(ctx, v, ct, flags);
+        return create(ctx, v, ct, flags);
+    }
+
+    /**
+     * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
+     *
+     * Used by the RenderScriptThunker to maintain backward compatibility.
+     *
+     * @hide
+     * @param ctx The context.
+     * @param sdkVersion The target SDK Version.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, int sdkVersion) {
+        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
+    }
+
+     /**
+     * Gets or creates a RenderScript context of the specified type.
+     *
+     * @hide
+     * @param ctx The context.
+     * @param ct The type of context to be created.
+     * @param sdkVersion The target SDK Version.
+     * @param flags The OR of the CREATE_FLAG_* options desired
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
+        if (sdkVersion < 23) {
+            return internalCreate(ctx, sdkVersion, ct, flags);
         }
 
         synchronized (mProcessContextList) {
             for (RenderScript prs : mProcessContextList) {
                 if ((prs.mContextType == ct) &&
                     (prs.mContextFlags == flags) &&
-                    (prs.mContextSdkVersion == v)) {
+                    (prs.mContextSdkVersion == sdkVersion)) {
 
                     return prs;
                 }
             }
 
-            RenderScript prs = internalCreate(ctx, v, ct, flags);
+            RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
             prs.mIsProcessContext = true;
             mProcessContextList.add(prs);
             return prs;
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 8fcdd39..31f9e22 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -22,6 +22,7 @@
 import android.app.IActivityManager;
 import android.app.IApplicationThread;
 import android.app.IBackupAgent;
+import android.app.PackageInstallObserver;
 import android.app.PendingIntent;
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupDataInput;
@@ -45,7 +46,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -200,7 +200,6 @@
 
     private static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
     private static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
-    private static final String RUN_CLEAR_ACTION = "android.app.backup.intent.CLEAR";
     private static final int MSG_RUN_BACKUP = 1;
     private static final int MSG_RUN_ADB_BACKUP = 2;
     private static final int MSG_RUN_RESTORE = 3;
@@ -1198,11 +1197,13 @@
                 temp = new RandomAccessFile(tempProcessedFile, "rws");
                 in = new RandomAccessFile(mEverStored, "r");
 
+                // Loop until we hit EOF
                 while (true) {
-                    PackageInfo info;
                     String pkg = in.readUTF();
                     try {
-                        info = mPackageManager.getPackageInfo(pkg, 0);
+                        // is this package still present?
+                        mPackageManager.getPackageInfo(pkg, 0);
+                        // if we get here then yes it is; remember it
                         mEverStoredApps.add(pkg);
                         temp.writeUTF(pkg);
                         if (MORE_DEBUG) Slog.v(TAG, "   + " + pkg);
@@ -4100,7 +4101,6 @@
 
             SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
                     AtomicBoolean latch) throws IOException {
-                int oldfd = output.getFd();
                 mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                 mTarget = target;
                 mLatch = latch;
@@ -4812,7 +4812,7 @@
             }
         }
 
-        class RestoreInstallObserver extends IPackageInstallObserver.Stub {
+        class RestoreInstallObserver extends PackageInstallObserver {
             final AtomicBoolean mDone = new AtomicBoolean();
             String mPackageName;
             int mResult;
@@ -4838,8 +4838,8 @@
             }
 
             @Override
-            public void packageInstalled(String packageName, int returnCode)
-                    throws RemoteException {
+            public void onPackageInstalled(String packageName, int returnCode,
+                    String msg, Bundle extras) {
                 synchronized (mDone) {
                     mResult = returnCode;
                     mPackageName = packageName;
@@ -5095,7 +5095,9 @@
                         offset = extractLine(buffer, offset, str);
                         version = Integer.parseInt(str[0]);  // app version
                         offset = extractLine(buffer, offset, str);
-                        int platformVersion = Integer.parseInt(str[0]);
+                        // This is the platform version, which we don't use, but we parse it
+                        // as a safety against corruption in the manifest.
+                        Integer.parseInt(str[0]);
                         offset = extractLine(buffer, offset, str);
                         info.installerPackageName = (str[0].length() > 0) ? str[0] : null;
                         offset = extractLine(buffer, offset, str);
@@ -6156,7 +6158,7 @@
             }
         }
 
-        class RestoreInstallObserver extends IPackageInstallObserver.Stub {
+        class RestoreInstallObserver extends PackageInstallObserver {
             final AtomicBoolean mDone = new AtomicBoolean();
             String mPackageName;
             int mResult;
@@ -6182,8 +6184,8 @@
             }
 
             @Override
-            public void packageInstalled(String packageName, int returnCode)
-                    throws RemoteException {
+            public void onPackageInstalled(String packageName, int returnCode,
+                    String msg, Bundle extras) {
                 synchronized (mDone) {
                     mResult = returnCode;
                     mPackageName = packageName;
@@ -6432,7 +6434,9 @@
                         offset = extractLine(buffer, offset, str);
                         version = Integer.parseInt(str[0]);  // app version
                         offset = extractLine(buffer, offset, str);
-                        int platformVersion = Integer.parseInt(str[0]);
+                        // This is the platform version, which we don't use, but we parse it
+                        // as a safety against corruption in the manifest.
+                        Integer.parseInt(str[0]);
                         offset = extractLine(buffer, offset, str);
                         info.installerPackageName = (str[0].length() > 0) ? str[0] : null;
                         offset = extractLine(buffer, offset, str);
@@ -8357,7 +8361,9 @@
             }
 
             // make sure the screen is lit for the user interaction
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
 
             // start the confirmation countdown
             startConfirmationTimeout(token, params);
@@ -8440,7 +8446,9 @@
             }
 
             // make sure the screen is lit for the user interaction
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
 
             // start the confirmation countdown
             startConfirmationTimeout(token, params);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index fd35b5e..4677f65 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -86,7 +86,10 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
 import android.text.style.SuggestionSpan;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.EventLog;
 import android.util.LruCache;
@@ -125,6 +128,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 
@@ -134,8 +138,12 @@
 public class InputMethodManagerService extends IInputMethodManager.Stub
         implements ServiceConnection, Handler.Callback {
     static final boolean DEBUG = false;
+    static final boolean DEBUG_RESTORE = DEBUG || false;
     static final String TAG = "InputMethodManagerService";
 
+    private static final char INPUT_METHOD_SEPARATOR = ':';
+    private static final char INPUT_METHOD_SUBTYPE_SEPARATOR = ';';
+
     static final int MSG_SHOW_IM_PICKER = 1;
     static final int MSG_SHOW_IM_SUBTYPE_PICKER = 2;
     static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 3;
@@ -466,12 +474,101 @@
                     || Intent.ACTION_USER_REMOVED.equals(action)) {
                 updateCurrentProfileIds();
                 return;
+            } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
+                final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
+                if (Settings.Secure.ENABLED_INPUT_METHODS.equals(name)) {
+                    final String prevValue = intent.getStringExtra(
+                            Intent.EXTRA_SETTING_PREVIOUS_VALUE);
+                    final String newValue = intent.getStringExtra(
+                            Intent.EXTRA_SETTING_NEW_VALUE);
+                    restoreEnabledInputMethods(mContext, prevValue, newValue);
+                }
             } else {
                 Slog.w(TAG, "Unexpected intent " + intent);
             }
         }
     }
 
+    // Apply the results of a restore operation to the set of enabled IMEs.  Note that this
+    // does not attempt to validate on the fly with any installed device policy, so must only
+    // be run in the context of initial device setup.
+    //
+    // TODO: Move this method to InputMethodUtils with adding unit tests.
+    static void restoreEnabledInputMethods(Context context, String prevValue, String newValue) {
+        if (DEBUG_RESTORE) {
+            Slog.i(TAG, "Restoring enabled input methods:");
+            Slog.i(TAG, "prev=" + prevValue);
+            Slog.i(TAG, " new=" + newValue);
+        }
+        // 'new' is the just-restored state, 'prev' is what was in settings prior to the restore
+        ArrayMap<String, ArraySet<String>> prevMap = parseInputMethodsAndSubtypesString(prevValue);
+        ArrayMap<String, ArraySet<String>> newMap = parseInputMethodsAndSubtypesString(newValue);
+
+        // Merge the restored ime+subtype enabled states into the live state
+        for (ArrayMap.Entry<String, ArraySet<String>> entry : newMap.entrySet()) {
+            final String imeId = entry.getKey();
+            ArraySet<String> prevSubtypes = prevMap.get(imeId);
+            if (prevSubtypes == null) {
+                prevSubtypes = new ArraySet<String>(2);
+                prevMap.put(imeId, prevSubtypes);
+            }
+            prevSubtypes.addAll(entry.getValue());
+        }
+
+        final String mergedImesAndSubtypesString = buildInputMethodsAndSubtypesString(prevMap);
+        if (DEBUG_RESTORE) {
+            Slog.i(TAG, "Merged IME string:");
+            Slog.i(TAG, "     " + mergedImesAndSubtypesString);
+        }
+        Settings.Secure.putString(context.getContentResolver(),
+                Settings.Secure.ENABLED_INPUT_METHODS, mergedImesAndSubtypesString);
+    }
+
+    // TODO: Move this method to InputMethodUtils with adding unit tests.
+    static String buildInputMethodsAndSubtypesString(ArrayMap<String, ArraySet<String>> map) {
+        // we want to use the canonical InputMethodSettings implementation,
+        // so we convert data structures first.
+        List<Pair<String, ArrayList<String>>> imeMap =
+                new ArrayList<Pair<String, ArrayList<String>>>(4);
+        for (ArrayMap.Entry<String, ArraySet<String>> entry : map.entrySet()) {
+            final String imeName = entry.getKey();
+            final ArraySet<String> subtypeSet = entry.getValue();
+            final ArrayList<String> subtypes = new ArrayList<String>(2);
+            if (subtypeSet != null) {
+                subtypes.addAll(subtypeSet);
+            }
+            imeMap.add(new Pair<String, ArrayList<String>>(imeName, subtypes));
+        }
+        return InputMethodSettings.buildInputMethodsSettingString(imeMap);
+    }
+
+    // TODO: Move this method to InputMethodUtils with adding unit tests.
+    static ArrayMap<String, ArraySet<String>> parseInputMethodsAndSubtypesString(
+            final String inputMethodsAndSubtypesString) {
+        final ArrayMap<String, ArraySet<String>> imeMap =
+                new ArrayMap<String, ArraySet<String>>();
+        if (TextUtils.isEmpty(inputMethodsAndSubtypesString)) {
+            return imeMap;
+        }
+
+        final SimpleStringSplitter typeSplitter =
+                new SimpleStringSplitter(INPUT_METHOD_SEPARATOR);
+        final SimpleStringSplitter subtypeSplitter =
+                new SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);
+        List<Pair<String, ArrayList<String>>> allImeSettings =
+                InputMethodSettings.buildInputMethodsAndSubtypeList(inputMethodsAndSubtypesString,
+                        typeSplitter,
+                        subtypeSplitter);
+        for (Pair<String, ArrayList<String>> ime : allImeSettings) {
+            ArraySet<String> subtypes = new ArraySet<String>();
+            if (ime.second != null) {
+                subtypes.addAll(ime.second);
+            }
+            imeMap.put(ime.first, subtypes);
+        }
+        return imeMap;
+    }
+
     class MyPackageMonitor extends PackageMonitor {
         private boolean isChangingPackagesOfCurrentUser() {
             final int userId = getChangingUserId();
@@ -675,6 +772,7 @@
         broadcastFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         broadcastFilter.addAction(Intent.ACTION_USER_ADDED);
         broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
+        broadcastFilter.addAction(Intent.ACTION_SETTING_RESTORED);
         mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);
 
         mNotificationShown = false;
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 1e3b46b..b8d9ec5 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -123,6 +123,27 @@
 
     // TODO: listen for user creation/deletion
 
+    public static class Lifecycle extends SystemService {
+        private MountService mMountService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mMountService = new MountService(getContext());
+            publishBinderService("mount", mMountService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mMountService.systemReady();
+            }
+        }
+    }
+
     private static final boolean LOCAL_LOGD = false;
     private static final boolean DEBUG_UNMOUNT = false;
     private static final boolean DEBUG_EVENTS = false;
@@ -574,7 +595,8 @@
 
     private final Handler mHandler;
 
-    void waitForAsecScan() {
+    @Override
+    public void waitForAsecScan() {
         waitForLatch(mAsecsScanned);
     }
 
@@ -1538,7 +1560,7 @@
         }
     }
 
-    public void systemReady() {
+    private void systemReady() {
         mSystemReady = true;
         mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
     }
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 6ad128c..4c9d7d3 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -71,9 +71,11 @@
     public static final class PermissionEntry {
         public final String name;
         public int[] gids;
+        public boolean perUser;
 
-        PermissionEntry(String _name) {
-            name = _name;
+        PermissionEntry(String name, boolean perUser) {
+            this.name = name;
+            this.perUser = perUser;
         }
     }
 
@@ -363,14 +365,14 @@
 
     void readPermission(XmlPullParser parser, String name)
             throws IOException, XmlPullParserException {
-
-        name = name.intern();
-
-        PermissionEntry perm = mPermissions.get(name);
-        if (perm == null) {
-            perm = new PermissionEntry(name);
-            mPermissions.put(name, perm);
+        if (mPermissions.containsKey(name)) {
+            throw new IllegalStateException("Duplicate permission definition for " + name);
         }
+
+        final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
+        final PermissionEntry perm = new PermissionEntry(name, perUser);
+        mPermissions.put(name, perm);
+
         int outerDepth = parser.getDepth();
         int type;
         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 87dc420..64f3070 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -157,7 +157,6 @@
     @Override
     public void onStart() {
         final Context context = getContext();
-        mTwilightManager = getLocalService(TwilightManager.class);
 
         final PowerManager powerManager =
                 (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -188,7 +187,11 @@
         mNightMode = Settings.Secure.getInt(context.getContentResolver(),
                 Settings.Secure.UI_NIGHT_MODE, defaultNightMode);
 
-        mTwilightManager.registerListener(mTwilightListener, mHandler);
+        // Update the initial, static configurations.
+        synchronized (this) {
+            updateConfigurationLocked();
+            sendConfigurationLocked();
+        }
 
         publishBinderService(Context.UI_MODE_SERVICE, mService);
     }
@@ -297,8 +300,11 @@
                     pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
             pw.print("  mHoldingConfiguration="); pw.print(mHoldingConfiguration);
                     pw.print(" mSystemReady="); pw.println(mSystemReady);
-            pw.print("  mTwilightService.getCurrentState()=");
-                    pw.println(mTwilightManager.getCurrentState());
+            if (mTwilightManager != null) {
+                // We may not have a TwilightManager.
+                pw.print("  mTwilightService.getCurrentState()=");
+                pw.println(mTwilightManager.getCurrentState());
+            }
         }
     }
 
@@ -306,6 +312,10 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             synchronized (mLock) {
+                mTwilightManager = getLocalService(TwilightManager.class);
+                if (mTwilightManager != null) {
+                    mTwilightManager.registerListener(mTwilightListener, mHandler);
+                }
                 mSystemReady = true;
                 mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
                 updateComputedNightModeLocked();
@@ -623,9 +633,11 @@
     }
 
     private void updateComputedNightModeLocked() {
-        TwilightState state = mTwilightManager.getCurrentState();
-        if (state != null) {
-            mComputedNightMode = state.isNight();
+        if (mTwilightManager != null) {
+            TwilightState state = mTwilightManager.getCurrentState();
+            if (state != null) {
+                mComputedNightMode = state.isNight();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 11c3ea6..626b442 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -76,6 +76,7 @@
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.os.Zygote;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.MemInfoReader;
@@ -1231,7 +1232,7 @@
                 TAG, "Death received in " + this
                 + " for thread " + mAppThread.asBinder());
             synchronized(ActivityManagerService.this) {
-                appDiedLocked(mApp, mPid, mAppThread);
+                appDiedLocked(mApp, mPid, mAppThread, true);
             }
         }
     }
@@ -3066,7 +3067,7 @@
                  * Add shared application and profile GIDs so applications can share some
                  * resources like shared libraries and access user-wide resources
                  */
-                if (permGids == null) {
+                if (ArrayUtils.isEmpty(permGids)) {
                     gids = new int[2];
                 } else {
                     gids = new int[permGids.length + 2];
@@ -4303,10 +4304,11 @@
     }
 
     final void appDiedLocked(ProcessRecord app) {
-       appDiedLocked(app, app.pid, app.thread);
+       appDiedLocked(app, app.pid, app.thread, false);
     }
 
-    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
+    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
+            boolean fromBinderDied) {
         // First check if this ProcessRecord is actually active for the pid.
         synchronized (mPidsSelfLocked) {
             ProcessRecord curProc = mPidsSelfLocked.get(pid);
@@ -4322,7 +4324,9 @@
         }
 
         if (!app.killed) {
-            Process.killProcessQuiet(pid);
+            if (!fromBinderDied) {
+                Process.killProcessQuiet(pid);
+            }
             Process.killProcessGroup(app.info.uid, pid);
             app.killed = true;
         }
@@ -6530,7 +6534,7 @@
         if (permission == null) {
             return PackageManager.PERMISSION_DENIED;
         }
-        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
+        return checkComponentPermission(permission, pid, uid, -1, true);
     }
 
     @Override
@@ -6550,7 +6554,7 @@
             pid = tlsIdentity.pid;
         }
 
-        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
+        return checkComponentPermission(permission, pid, uid, -1, true);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 8fe1238..34c1c53 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -765,7 +765,7 @@
                 try {
                     perm = AppGlobals.getPackageManager().
                             checkPermission(r.requiredPermission,
-                                    info.activityInfo.applicationInfo.packageName);
+                                    info.activityInfo.applicationInfo.packageName, r.userId);
                 } catch (RemoteException e) {
                     perm = PackageManager.PERMISSION_DENIED;
                 }
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a530dfa..65949bf 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -55,6 +55,7 @@
 import android.speech.RecognizerIntent;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.view.KeyEvent;
 
@@ -743,15 +744,23 @@
                 Log.w(TAG, "Attempted to dispatch null or non-media key event.");
                 return;
             }
+
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
-            if (DEBUG) {
-                Log.d(TAG, "dispatchMediaKeyEvent, pid=" + pid + ", uid=" + uid + ", event="
-                        + keyEvent);
-            }
-
             try {
+                if (DEBUG) {
+                    Log.d(TAG, "dispatchMediaKeyEvent, pid=" + pid + ", uid=" + uid + ", event="
+                            + keyEvent);
+                }
+                if (!isUserSetupComplete()) {
+                    // Global media key handling can have the side-effect of starting new
+                    // activities which is undesirable while setup is in progress.
+                    Slog.i(TAG, "Not dispatching media key event because user "
+                            + "setup is in progress.");
+                    return;
+                }
+
                 synchronized (mLock) {
                     // If we don't have a media button receiver to fall back on
                     // include non-playing sessions for dispatching
@@ -1025,6 +1034,11 @@
             return keyCode == KeyEvent.KEYCODE_HEADSETHOOK;
         }
 
+        private boolean isUserSetupComplete() {
+            return Settings.Secure.getIntForUser(getContext().getContentResolver(),
+                    Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+        }
+
         // we only handle public stream types, which are 0-5
         private boolean isValidLocalStreamType(int streamType) {
             return streamType >= AudioManager.STREAM_VOICE_CALL
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 1335706..22cdd58 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -18,6 +18,7 @@
 
 import android.app.Notification;
 import android.content.Context;
+import android.util.Log;
 import android.util.Slog;
 
 /**
@@ -25,8 +26,8 @@
  * notifications and marks them to get a temporary ranking bump.
  */
 public class NotificationIntrusivenessExtractor implements NotificationSignalExtractor {
-    private static final String TAG = "NotificationNoiseExtractor";
-    private static final boolean DBG = false;
+    private static final String TAG = "IntrusivenessExtractor";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
 
     /** Length of time (in milliseconds) that an intrusive or noisy notification will stay at
     the top of the ranking order, before it falls back to its natural position. */
@@ -48,7 +49,7 @@
                 (notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
                 notification.sound != null ||
                 notification.fullScreenIntent != null) {
-            record.setRecentlyIntusive(true);
+            record.setRecentlyIntrusive(true);
         }
 
         return new RankingReconsideration(record.getKey(), HANG_TIME_MS) {
@@ -59,7 +60,7 @@
 
             @Override
             public void applyChangesLocked(NotificationRecord record) {
-                record.setRecentlyIntusive(false);
+                record.setRecentlyIntrusive(false);
             }
         };
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0c71d5f..c330046 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1216,6 +1216,19 @@
         }
 
         @Override
+        public void setPackagePeekable(String pkg, int uid, boolean peekable) {
+            checkCallerIsSystem();
+
+            mRankingHelper.setPackagePeekable(pkg, uid, peekable);
+        }
+
+        @Override
+        public boolean getPackagePeekable(String pkg, int uid) {
+            checkCallerIsSystem();
+            return mRankingHelper.getPackagePeekable(pkg, uid);
+        }
+
+        @Override
         public void setPackageVisibilityOverride(String pkg, int uid, int visibility) {
             checkCallerIsSystem();
             mRankingHelper.setPackageVisibilityOverride(pkg, uid, visibility);
@@ -1845,6 +1858,14 @@
                             notification.priority = Notification.PRIORITY_HIGH;
                         }
                     }
+                    // force no heads up per package config
+                    if (!mRankingHelper.getPackagePeekable(pkg, callingUid)) {
+                        if (notification.extras == null) {
+                            notification.extras = new Bundle();
+                        }
+                        notification.extras.putInt(Notification.EXTRA_AS_HEADS_UP,
+                                Notification.HEADS_UP_NEVER);
+                    }
 
                     // 1. initial score: buckets of 10, around the app [-20..20]
                     final int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index ea6f2db..39fd9ab 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -209,7 +209,7 @@
         return mContactAffinity;
     }
 
-    public void setRecentlyIntusive(boolean recentlyIntrusive) {
+    public void setRecentlyIntrusive(boolean recentlyIntrusive) {
         mRecentlyIntrusive = recentlyIntrusive;
     }
 
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index aea137b..803db10 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -20,6 +20,10 @@
 
     void setPackagePriority(String packageName, int uid, int priority);
 
+    boolean getPackagePeekable(String packageName, int uid);
+
+    void setPackagePeekable(String packageName, int uid, boolean peekable);
+
     int getPackageVisibilityOverride(String packageName, int uid);
 
     void setPackageVisibilityOverride(String packageName, int uid, int visibility);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 518e223..88055ba 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -23,9 +23,8 @@
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Slog;
-import android.util.SparseIntArray;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -34,12 +33,10 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 public class RankingHelper implements RankingConfig {
     private static final String TAG = "RankingHelper";
-    private static final boolean DEBUG = false;
 
     private static final int XML_VERSION = 1;
 
@@ -50,16 +47,20 @@
     private static final String ATT_NAME = "name";
     private static final String ATT_UID = "uid";
     private static final String ATT_PRIORITY = "priority";
+    private static final String ATT_PEEKABLE = "peekable";
     private static final String ATT_VISIBILITY = "visibility";
 
+    private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
+    private static final boolean DEFAULT_PEEKABLE = true;
+    private static final int DEFAULT_VISIBILITY =
+            NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+
     private final NotificationSignalExtractor[] mSignalExtractors;
     private final NotificationComparator mPreliminaryComparator = new NotificationComparator();
     private final GlobalSortKeyComparator mFinalComparator = new GlobalSortKeyComparator();
 
-    // Package name to uid, to priority. Would be better as Table<String, Int, Int>
-    private final ArrayMap<String, SparseIntArray> mPackagePriorities;
-    private final ArrayMap<String, SparseIntArray> mPackageVisibilities;
-    private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp;
+    private final ArrayMap<String, Record> mRecords = new ArrayMap<>(); // pkg|uid => Record
+    private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp = new ArrayMap<>();
 
     private final Context mContext;
     private final Handler mRankingHandler;
@@ -67,8 +68,6 @@
     public RankingHelper(Context context, Handler rankingHandler, String[] extractorNames) {
         mContext = context;
         mRankingHandler = rankingHandler;
-        mPackagePriorities = new ArrayMap<String, SparseIntArray>();
-        mPackageVisibilities = new ArrayMap<String, SparseIntArray>();
 
         final int N = extractorNames.length;
         mSignalExtractors = new NotificationSignalExtractor[N];
@@ -88,9 +87,9 @@
                 Slog.w(TAG, "Problem accessing extractor " + extractorNames[i] + ".", e);
             }
         }
-        mProxyByGroupTmp = new ArrayMap<String, NotificationRecord>();
     }
 
+    @SuppressWarnings("unchecked")
     public <T extends NotificationSignalExtractor> T findExtractor(Class<T> extractorClass) {
         final int N = mSignalExtractors.length;
         for (int i = 0; i < N; i++) {
@@ -125,8 +124,7 @@
         if (type != XmlPullParser.START_TAG) return;
         String tag = parser.getName();
         if (!TAG_RANKING.equals(tag)) return;
-        mPackagePriorities.clear();
-        final int version = safeInt(parser, ATT_VERSION, XML_VERSION);
+        mRecords.clear();
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
             tag = parser.getName();
             if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
@@ -135,27 +133,20 @@
             if (type == XmlPullParser.START_TAG) {
                 if (TAG_PACKAGE.equals(tag)) {
                     int uid = safeInt(parser, ATT_UID, UserHandle.USER_ALL);
-                    int priority = safeInt(parser, ATT_PRIORITY, Notification.PRIORITY_DEFAULT);
-                    int vis = safeInt(parser, ATT_VISIBILITY,
-                            NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
+                    int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+                    boolean peekable = safeBool(parser, ATT_PEEKABLE, DEFAULT_PEEKABLE);
+                    int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
                     String name = parser.getAttributeValue(null, ATT_NAME);
 
                     if (!TextUtils.isEmpty(name)) {
-                        if (priority != Notification.PRIORITY_DEFAULT) {
-                            SparseIntArray priorityByUid = mPackagePriorities.get(name);
-                            if (priorityByUid == null) {
-                                priorityByUid = new SparseIntArray();
-                                mPackagePriorities.put(name, priorityByUid);
-                            }
-                            priorityByUid.put(uid, priority);
+                        if (priority != DEFAULT_PRIORITY) {
+                            getOrCreateRecord(name, uid).priority = priority;
                         }
-                        if (vis != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
-                            SparseIntArray visibilityByUid = mPackageVisibilities.get(name);
-                            if (visibilityByUid == null) {
-                                visibilityByUid = new SparseIntArray();
-                                mPackageVisibilities.put(name, visibilityByUid);
-                            }
-                            visibilityByUid.put(uid, vis);
+                        if (peekable != DEFAULT_PEEKABLE) {
+                            getOrCreateRecord(name, uid).peekable = peekable;
+                        }
+                        if (vis != DEFAULT_VISIBILITY) {
+                            getOrCreateRecord(name, uid).visibility = vis;
                         }
                     }
                 }
@@ -164,49 +155,53 @@
         throw new IllegalStateException("Failed to reach END_DOCUMENT");
     }
 
+    private static String recordKey(String pkg, int uid) {
+        return pkg + "|" + uid;
+    }
+
+    private Record getOrCreateRecord(String pkg, int uid) {
+        final String key = recordKey(pkg, uid);
+        Record r = mRecords.get(key);
+        if (r == null) {
+            r = new Record();
+            r.pkg = pkg;
+            r.uid = uid;
+            mRecords.put(key, r);
+        }
+        return r;
+    }
+
+    private void removeDefaultRecords() {
+        final int N = mRecords.size();
+        for (int i = N - 1; i >= 0; i--) {
+            final Record r = mRecords.valueAt(i);
+            if (r.priority == DEFAULT_PRIORITY && r.peekable == DEFAULT_PEEKABLE
+                    && r.visibility == DEFAULT_VISIBILITY) {
+                mRecords.remove(i);
+            }
+        }
+    }
+
     public void writeXml(XmlSerializer out) throws IOException {
         out.startTag(null, TAG_RANKING);
         out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
 
-        final Set<String> packageNames = new ArraySet<>(mPackagePriorities.size()
-                + mPackageVisibilities.size());
-        packageNames.addAll(mPackagePriorities.keySet());
-        packageNames.addAll(mPackageVisibilities.keySet());
-        final Set<Integer> packageUids = new ArraySet<>();
-        for (String packageName : packageNames) {
-            packageUids.clear();
-            SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
-            SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
-            if (priorityByUid != null) {
-                final int M = priorityByUid.size();
-                for (int j = 0; j < M; j++) {
-                    packageUids.add(priorityByUid.keyAt(j));
-                }
+        final int N = mRecords.size();
+        for (int i = 0; i < N; i++) {
+            final Record r = mRecords.valueAt(i);
+            out.startTag(null, TAG_PACKAGE);
+            out.attribute(null, ATT_NAME, r.pkg);
+            if (r.priority != DEFAULT_PRIORITY) {
+                out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
             }
-            if (visibilityByUid != null) {
-                final int M = visibilityByUid.size();
-                for (int j = 0; j < M; j++) {
-                    packageUids.add(visibilityByUid.keyAt(j));
-                }
+            if (r.peekable != DEFAULT_PEEKABLE) {
+                out.attribute(null, ATT_PEEKABLE, Boolean.toString(r.peekable));
             }
-            for (Integer uid : packageUids) {
-                out.startTag(null, TAG_PACKAGE);
-                out.attribute(null, ATT_NAME, packageName);
-                if (priorityByUid != null) {
-                    final int priority = priorityByUid.get(uid);
-                    if (priority != Notification.PRIORITY_DEFAULT) {
-                        out.attribute(null, ATT_PRIORITY, Integer.toString(priority));
-                    }
-                }
-                if (visibilityByUid != null) {
-                    final int visibility = visibilityByUid.get(uid);
-                    if (visibility != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
-                        out.attribute(null, ATT_VISIBILITY, Integer.toString(visibility));
-                    }
-                }
-                out.attribute(null, ATT_UID, Integer.toString(uid));
-                out.endTag(null, TAG_PACKAGE);
+            if (r.visibility != DEFAULT_VISIBILITY) {
+                out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
             }
+            out.attribute(null, ATT_UID, Integer.toString(r.uid));
+            out.endTag(null, TAG_PACKAGE);
         }
         out.endTag(null, TAG_RANKING);
     }
@@ -295,14 +290,20 @@
         }
     }
 
+    private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
+        final String val = parser.getAttributeValue(null, att);
+        return tryParseBool(val, defValue);
+    }
+
+    private static boolean tryParseBool(String value, boolean defValue) {
+        if (TextUtils.isEmpty(value)) return defValue;
+        return Boolean.valueOf(value);
+    }
+
     @Override
     public int getPackagePriority(String packageName, int uid) {
-        int priority = Notification.PRIORITY_DEFAULT;
-        SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
-        if (priorityByUid != null) {
-            priority = priorityByUid.get(uid, Notification.PRIORITY_DEFAULT);
-        }
-        return priority;
+        final Record r = mRecords.get(recordKey(packageName, uid));
+        return r != null ? r.priority : DEFAULT_PRIORITY;
     }
 
     @Override
@@ -310,24 +311,31 @@
         if (priority == getPackagePriority(packageName, uid)) {
             return;
         }
-        SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
-        if (priorityByUid == null) {
-            priorityByUid = new SparseIntArray();
-            mPackagePriorities.put(packageName, priorityByUid);
+        getOrCreateRecord(packageName, uid).priority = priority;
+        removeDefaultRecords();
+        updateConfig();
+    }
+
+    @Override
+    public boolean getPackagePeekable(String packageName, int uid) {
+        final Record r = mRecords.get(recordKey(packageName, uid));
+        return r != null ? r.peekable : DEFAULT_PEEKABLE;
+    }
+
+    @Override
+    public void setPackagePeekable(String packageName, int uid, boolean peekable) {
+        if (peekable == getPackagePeekable(packageName, uid)) {
+            return;
         }
-        priorityByUid.put(uid, priority);
+        getOrCreateRecord(packageName, uid).peekable = peekable;
+        removeDefaultRecords();
         updateConfig();
     }
 
     @Override
     public int getPackageVisibilityOverride(String packageName, int uid) {
-        int visibility = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
-        SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
-        if (visibilityByUid != null) {
-            visibility = visibilityByUid.get(uid,
-                    NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
-        }
-        return visibility;
+        final Record r = mRecords.get(recordKey(packageName, uid));
+        return r != null ? r.visibility : DEFAULT_VISIBILITY;
     }
 
     @Override
@@ -335,12 +343,8 @@
         if (visibility == getPackageVisibilityOverride(packageName, uid)) {
             return;
         }
-        SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
-        if (visibilityByUid == null) {
-            visibilityByUid = new SparseIntArray();
-            mPackageVisibilities.put(packageName, visibilityByUid);
-        }
-        visibilityByUid.put(uid, visibility);
+        getOrCreateRecord(packageName, uid).visibility = visibility;
+        removeDefaultRecords();
         updateConfig();
     }
 
@@ -356,28 +360,42 @@
                 pw.println(mSignalExtractors[i]);
             }
         }
-        final int N = mPackagePriorities.size();
         if (filter == null) {
             pw.print(prefix);
-            pw.println("package priorities:");
+            pw.println("per-package config:");
         }
+        final int N = mRecords.size();
         for (int i = 0; i < N; i++) {
-            String name = mPackagePriorities.keyAt(i);
-            if (filter == null || filter.matches(name)) {
-                SparseIntArray priorityByUid = mPackagePriorities.get(name);
-                final int M = priorityByUid.size();
-                for (int j = 0; j < M; j++) {
-                    int uid = priorityByUid.keyAt(j);
-                    int priority = priorityByUid.get(uid);
-                    pw.print(prefix);
-                    pw.print("  ");
-                    pw.print(name);
-                    pw.print(" (");
-                    pw.print(uid);
-                    pw.print(") has priority: ");
-                    pw.println(priority);
+            final Record r = mRecords.valueAt(i);
+            if (filter == null || filter.matches(r.pkg)) {
+                pw.print(prefix);
+                pw.print("  ");
+                pw.print(r.pkg);
+                pw.print(" (");
+                pw.print(r.uid);
+                pw.print(')');
+                if (r.priority != DEFAULT_PRIORITY) {
+                    pw.print(" priority=");
+                    pw.print(Notification.priorityToString(r.priority));
                 }
+                if (r.peekable != DEFAULT_PEEKABLE) {
+                    pw.print(" peekable=");
+                    pw.print(r.peekable);
+                }
+                if (r.visibility != DEFAULT_VISIBILITY) {
+                    pw.print(" visibility=");
+                    pw.print(Notification.visibilityToString(r.visibility));
+                }
+                pw.println();
             }
         }
     }
+
+    private static class Record {
+        String pkg;
+        int uid;
+        int priority = DEFAULT_PRIORITY;
+        boolean peekable = DEFAULT_PEEKABLE;
+        int visibility = DEFAULT_VISIBILITY;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java
index 4f27408..ec290ef3 100644
--- a/services/core/java/com/android/server/pm/BasePermission.java
+++ b/services/core/java/com/android/server/pm/BasePermission.java
@@ -18,6 +18,9 @@
 
 import android.content.pm.PackageParser;
 import android.content.pm.PermissionInfo;
+import android.os.UserHandle;
+
+import com.android.internal.util.ArrayUtils;
 
 final class BasePermission {
     final static int TYPE_NORMAL = 0;
@@ -40,9 +43,17 @@
 
     PermissionInfo pendingInfo;
 
+    /** UID that owns the definition of this permission */
     int uid;
 
-    int[] gids;
+    /** Additional GIDs given to apps granted this permission */
+    private int[] gids;
+
+    /**
+     * Flag indicating that {@link #gids} should be adjusted based on the
+     * {@link UserHandle} the granted app is running as.
+     */
+    private boolean perUser;
 
     BasePermission(String _name, String _sourcePackage, int _type) {
         name = _name;
@@ -52,8 +63,35 @@
         protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
     }
 
+    @Override
     public String toString() {
         return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name
                 + "}";
     }
+
+    public void setGids(int[] gids, boolean perUser) {
+        this.gids = gids;
+        this.perUser = perUser;
+    }
+
+    public boolean hasGids() {
+        return ArrayUtils.isEmpty(gids);
+    }
+
+    public int[] computeGids(int userId) {
+        if (perUser) {
+            final int[] userGids = new int[gids.length];
+            for (int i = 0; i < gids.length; i++) {
+                userGids[i] = UserHandle.getUid(userId, gids[i]);
+            }
+            return userGids;
+        } else {
+            return gids;
+        }
+    }
+
+    public boolean isRuntime() {
+        return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+                == PermissionInfo.PROTECTION_DANGEROUS;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 52411bf..2629e48 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -54,7 +54,6 @@
 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
 import static com.android.internal.util.ArrayUtils.appendInt;
-import static com.android.internal.util.ArrayUtils.removeInt;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
@@ -249,6 +248,9 @@
     private static final boolean DEBUG_DEXOPT = false;
     private static final boolean DEBUG_ABI_SELECTION = false;
 
+    private static final boolean RUNTIME_PERMISSIONS_ENABLED =
+            SystemProperties.getInt("ro.runtime.premissions.enabled", 0) == 1;
+
     private static final int RADIO_UID = Process.PHONE_UID;
     private static final int LOG_UID = Process.LOG_UID;
     private static final int NFC_UID = Process.NFC_UID;
@@ -321,10 +323,28 @@
             DEFAULT_CONTAINER_PACKAGE,
             "com.android.defcontainer.DefaultContainerService");
 
+    private static final String KILL_APP_REASON_GIDS_CHANGED =
+            "permission grant or revoke changed gids";
+
+    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
+            "permissions revoked";
+
     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
 
     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
 
+    /** Permission grant: not grant the permission. */
+    private static final int GRANT_DENIED = 1;
+
+    /** Permission grant: grant the permission as an install permission. */
+    private static final int GRANT_INSTALL = 2;
+
+    /** Permission grant: grant the permission as a runtime permission. */
+    private static final int GRANT_RUNTIME = 3;
+
+    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
+    private static final int GRANT_UPGRADE = 4;
+
     final ServiceThread mHandlerThread;
 
     final PackageHandler mHandler;
@@ -994,6 +1014,15 @@
                             res.removedInfo.sendBroadcast(false, true, false);
                             Bundle extras = new Bundle(1);
                             extras.putInt(Intent.EXTRA_UID, res.uid);
+
+                            // Now that we successfully installed the package, grant runtime
+                            // permissions if requested before broadcasting the install.
+                            if ((args.installFlags
+                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) {
+                                grantRequestedRuntimePermissions(res.pkg,
+                                        args.user.getIdentifier());
+                            }
+
                             // Determine the set of users who are adding this
                             // package for the first time vs. those who are seeing
                             // an update.
@@ -1214,6 +1243,32 @@
         }
     }
 
+    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) {
+        if (userId >= UserHandle.USER_OWNER) {
+            grantRequestedRuntimePermissionsForUser(pkg, userId);
+        } else if (userId == UserHandle.USER_ALL) {
+            for (int someUserId : UserManagerService.getInstance().getUserIds()) {
+                grantRequestedRuntimePermissionsForUser(pkg, someUserId);
+            }
+        }
+    }
+
+    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) {
+        SettingBase sb = (SettingBase) pkg.mExtras;
+        if (sb == null) {
+            return;
+        }
+
+        PermissionsState permissionsState = sb.getPermissionsState();
+
+        for (String permission : pkg.requestedPermissions) {
+            BasePermission bp = mSettings.mPermissions.get(permission);
+            if (bp != null && bp.isRuntime()) {
+                permissionsState.grantRuntimePermission(bp, userId);
+            }
+        }
+    }
+
     Bundle extrasForInstallResult(PackageInstalledInfo res) {
         Bundle extras = null;
         switch (res.returnCode) {
@@ -1243,7 +1298,7 @@
         }
     }
 
-    public static final PackageManagerService main(Context context, Installer installer,
+    public static PackageManagerService main(Context context, Installer installer,
             boolean factoryTest, boolean onlyCore) {
         PackageManagerService m = new PackageManagerService(context, installer,
                 factoryTest, onlyCore);
@@ -1293,7 +1348,7 @@
         mOnlyCore = onlyCore;
         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
         mMetrics = new DisplayMetrics();
-        mSettings = new Settings(context);
+        mSettings = new Settings(mContext, mPackages);
         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
@@ -1374,7 +1429,7 @@
                     mSettings.mPermissions.put(perm.name, bp);
                 }
                 if (perm.gids != null) {
-                    bp.gids = appendInts(bp.gids, perm.gids);
+                    bp.setGids(perm.gids, perm.perUser);
                 }
             }
 
@@ -1832,14 +1887,8 @@
 
             final String packageName = info.activityInfo.packageName;
 
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
-            if (ps == null) {
-                continue;
-            }
-
-            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
-            if (!gp.grantedPermissions
-                    .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
+            if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                    packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
                 continue;
             }
 
@@ -1895,26 +1944,21 @@
         return cur;
     }
 
-    static int[] removeInts(int[] cur, int[] rem) {
-        if (rem == null) return cur;
-        if (cur == null) return cur;
-        final int N = rem.length;
-        for (int i=0; i<N; i++) {
-            cur = removeInt(cur, rem[i]);
-        }
-        return cur;
-    }
-
     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
         final PackageSetting ps = (PackageSetting) p.mExtras;
         if (ps == null) {
             return null;
         }
-        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+
+        PermissionsState permissionsState = ps.getPermissionsState();
+
+        final int[] gids = permissionsState.computeGids(userId);
+        Set<String> permissions = permissionsState.getPermissions(userId);
+
         final PackageUserState state = ps.readUserState(userId);
-        return PackageParser.generatePackageInfo(p, gp.gids, flags,
-                ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
+        return PackageParser.generatePackageInfo(p, gids, flags,
+                ps.firstInstallTime, ps.lastUpdateTime, permissions,
                 state, userId);
     }
 
@@ -1986,6 +2030,7 @@
     public int getPackageUid(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return -1;
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
+
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -2002,22 +2047,30 @@
     }
 
     @Override
-    public int[] getPackageGids(String packageName) {
+    public int[] getPackageGids(String packageName, int userId) throws RemoteException {
+        if (!sUserManager.exists(userId)) {
+            return null;
+        }
+
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
+                "getPackageGids");
+
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
-            if (DEBUG_PACKAGE_INFO)
+            if (DEBUG_PACKAGE_INFO) {
                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
+            }
             if (p != null) {
-                final PackageSetting ps = (PackageSetting)p.mExtras;
-                return ps.getGids();
+                PackageSetting ps = (PackageSetting) p.mExtras;
+                return ps.getPermissionsState().computeGids(userId);
             }
         }
-        // stupid thing to indicate an error.
-        return new int[0];
+
+        return null;
     }
 
-    static final PermissionInfo generatePermissionInfo(
+    static PermissionInfo generatePermissionInfo(
             BasePermission bp, int flags) {
         if (bp.perm != null) {
             return PackageParser.generatePermissionInfo(bp.perm, flags);
@@ -2381,30 +2434,37 @@
     }
 
     @Override
-    public int checkPermission(String permName, String pkgName) {
+    public int checkPermission(String permName, String pkgName, int userId) {
+        if (!sUserManager.exists(userId)) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+
         synchronized (mPackages) {
-            PackageParser.Package p = mPackages.get(pkgName);
+            final PackageParser.Package p = mPackages.get(pkgName);
             if (p != null && p.mExtras != null) {
-                PackageSetting ps = (PackageSetting)p.mExtras;
-                if (ps.sharedUser != null) {
-                    if (ps.sharedUser.grantedPermissions.contains(permName)) {
-                        return PackageManager.PERMISSION_GRANTED;
-                    }
-                } else if (ps.grantedPermissions.contains(permName)) {
+                final PackageSetting ps = (PackageSetting) p.mExtras;
+                if (ps.getPermissionsState().hasPermission(permName, userId)) {
                     return PackageManager.PERMISSION_GRANTED;
                 }
             }
         }
+
         return PackageManager.PERMISSION_DENIED;
     }
 
     @Override
     public int checkUidPermission(String permName, int uid) {
+        final int userId = UserHandle.getUserId(uid);
+
+        if (!sUserManager.exists(userId)) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+
         synchronized (mPackages) {
             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
             if (obj != null) {
-                GrantedPermissions gp = (GrantedPermissions)obj;
-                if (gp.grantedPermissions.contains(permName)) {
+                final SettingBase ps = (SettingBase) obj;
+                if (ps.getPermissionsState().hasPermission(permName, userId)) {
                     return PackageManager.PERMISSION_GRANTED;
                 }
             } else {
@@ -2414,6 +2474,7 @@
                 }
             }
         }
+
         return PackageManager.PERMISSION_DENIED;
     }
 
@@ -2620,120 +2681,114 @@
         }
     }
 
-    private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
+    private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg,
+            BasePermission bp) {
         int index = pkg.requestedPermissions.indexOf(bp.name);
         if (index == -1) {
             throw new SecurityException("Package " + pkg.packageName
                     + " has not requested permission " + bp.name);
         }
-        boolean isNormal =
-                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
-                        == PermissionInfo.PROTECTION_NORMAL);
-        boolean isDangerous =
-                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
-                        == PermissionInfo.PROTECTION_DANGEROUS);
-        boolean isDevelopment =
-                ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
-
-        if (!isNormal && !isDangerous && !isDevelopment) {
+        if (!bp.isRuntime()) {
             throw new SecurityException("Permission " + bp.name
                     + " is not a changeable permission type");
         }
-
-        if (isNormal || isDangerous) {
-            if (pkg.requestedPermissionsRequired.get(index)) {
-                throw new SecurityException("Can't change " + bp.name
-                        + ". It is required by the application");
-            }
-        }
     }
 
     @Override
-    public void grantPermission(String packageName, String permissionName) {
+    public boolean grantPermission(String packageName, String name, int userId) {
+        if (!sUserManager.exists(userId)) {
+            return false;
+        }
+
         mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
+                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+                "grantPermission");
+
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "grantPermission");
+
         synchronized (mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
             if (pkg == null) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            final BasePermission bp = mSettings.mPermissions.get(permissionName);
+
+            final BasePermission bp = mSettings.mPermissions.get(name);
             if (bp == null) {
-                throw new IllegalArgumentException("Unknown permission: " + permissionName);
+                throw new IllegalArgumentException("Unknown permission: " + name);
             }
 
-            checkGrantRevokePermissions(pkg, bp);
+            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
 
-            final PackageSetting ps = (PackageSetting) pkg.mExtras;
-            if (ps == null) {
-                return;
+            final SettingBase sb = (SettingBase) pkg.mExtras;
+            if (sb == null) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
-            if (gp.grantedPermissions.add(permissionName)) {
-                if (ps.haveGids) {
-                    gp.gids = appendInts(gp.gids, bp.gids);
+
+            final PermissionsState permissionsState = sb.getPermissionsState();
+
+            final int result = permissionsState.grantRuntimePermission(bp, userId);
+            switch (result) {
+                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
+                    return false;
                 }
-                mSettings.writeLPr();
+
+                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
+                    killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
+                } break;
             }
+
+            // Not critical if that is lost - app has to request again.
+            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+
+            return true;
         }
     }
 
     @Override
-    public void revokePermission(String packageName, String permissionName) {
-        int changedAppId = -1;
+    public boolean revokePermission(String packageName, String name, int userId) {
+        if (!sUserManager.exists(userId)) {
+            return false;
+        }
+
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+                "revokePermission");
+
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "revokePermission");
 
         synchronized (mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
             if (pkg == null) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
-            }
-            final BasePermission bp = mSettings.mPermissions.get(permissionName);
+
+            final BasePermission bp = mSettings.mPermissions.get(name);
             if (bp == null) {
-                throw new IllegalArgumentException("Unknown permission: " + permissionName);
+                throw new IllegalArgumentException("Unknown permission: " + name);
             }
 
-            checkGrantRevokePermissions(pkg, bp);
+            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
 
-            final PackageSetting ps = (PackageSetting) pkg.mExtras;
-            if (ps == null) {
-                return;
+            final SettingBase sb = (SettingBase) pkg.mExtras;
+            if (sb == null) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
-            if (gp.grantedPermissions.remove(permissionName)) {
-                gp.grantedPermissions.remove(permissionName);
-                if (ps.haveGids) {
-                    gp.gids = removeInts(gp.gids, bp.gids);
-                }
-                mSettings.writeLPr();
-                changedAppId = ps.appId;
-            }
-        }
 
-        if (changedAppId >= 0) {
-            // We changed the perm on someone, kill its processes.
-            IActivityManager am = ActivityManagerNative.getDefault();
-            if (am != null) {
-                final int callingUserId = UserHandle.getCallingUserId();
-                final long ident = Binder.clearCallingIdentity();
-                try {
-                    //XXX we should only revoke for the calling user's app permissions,
-                    // but for now we impact all users.
-                    //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
-                    //        "revoke " + permissionName);
-                    int[] users = sUserManager.getUserIds();
-                    for (int user : users) {
-                        am.killUid(UserHandle.getUid(user, changedAppId),
-                                "revoke " + permissionName);
-                    }
-                } catch (RemoteException e) {
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
+            final PermissionsState permissionsState = sb.getPermissionsState();
+
+            if (permissionsState.revokeRuntimePermission(bp, userId) ==
+                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                return false;
             }
+
+            killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
+
+            // Critical, after this call all should never have the permission.
+            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
+
+            return true;
         }
     }
 
@@ -2794,6 +2849,46 @@
         }
     }
 
+    private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (sb instanceof SharedUserSetting) {
+                SharedUserSetting sus = (SharedUserSetting) sb;
+                final int packageCount = sus.packages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    PackageSetting susPs = sus.packages.valueAt(i);
+                    if (userId == UserHandle.USER_ALL) {
+                        killApplication(susPs.pkg.packageName, susPs.appId, reason);
+                    } else {
+                        final int uid = UserHandle.getUid(userId, susPs.appId);
+                        killUid(uid, reason);
+                    }
+                }
+            } else if (sb instanceof PackageSetting) {
+                PackageSetting ps = (PackageSetting) sb;
+                if (userId == UserHandle.USER_ALL) {
+                    killApplication(ps.pkg.packageName, ps.appId, reason);
+                } else {
+                    final int uid = UserHandle.getUid(userId, ps.appId);
+                    killUid(uid, reason);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private static void killUid(int uid, String reason) {
+        IActivityManager am = ActivityManagerNative.getDefault();
+        if (am != null) {
+            try {
+                am.killUid(uid, reason);
+            } catch (RemoteException e) {
+                /* ignore - same process */
+            }
+        }
+    }
+
     /**
      * Compares two sets of signatures. Returns:
      * <br />
@@ -3875,9 +3970,10 @@
     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
             String[] permissions, boolean[] tmp, int flags, int userId) {
         int numMatch = 0;
-        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+        final PermissionsState permissionsState = ps.getPermissionsState();
         for (int i=0; i<permissions.length; i++) {
-            if (gp.grantedPermissions.contains(permissions[i])) {
+            final String permission = permissions[i];
+            if (permissionsState.hasPermission(permission, userId)) {
                 tmp[i] = true;
                 numMatch++;
             } else {
@@ -6853,36 +6949,42 @@
 
     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
             String packageOfInterest) {
+        // IMPORTANT: There are two types of permissions: install and runtime.
+        // Install time permissions are granted when the app is installed to
+        // all device users and users added in the future. Runtime permissions
+        // are granted at runtime explicitly to specific users. Normal and signature
+        // protected permissions are install time permissions. Dangerous permissions
+        // are install permissions if the app's target SDK is Lollipop MR1 or older,
+        // otherwise they are runtime permissions. This function does not manage
+        // runtime permissions except for the case an app targeting Lollipop MR1
+        // being upgraded to target a newer SDK, in which case dangerous permissions
+        // are transformed from install time to runtime ones.
+
         final PackageSetting ps = (PackageSetting) pkg.mExtras;
         if (ps == null) {
             return;
         }
-        final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
-        ArraySet<String> origPermissions = gp.grantedPermissions;
+
+        PermissionsState permissionsState = ps.getPermissionsState();
+        PermissionsState origPermissions = permissionsState;
+
         boolean changedPermission = false;
 
         if (replace) {
             ps.permissionsFixed = false;
-            if (gp == ps) {
-                origPermissions = new ArraySet<String>(gp.grantedPermissions);
-                gp.grantedPermissions.clear();
-                gp.gids = mGlobalGids;
-            }
+            origPermissions = new PermissionsState(permissionsState);
+            permissionsState.reset();
         }
 
-        if (gp.gids == null) {
-            gp.gids = mGlobalGids;
-        }
+        permissionsState.setGlobalGids(mGlobalGids);
 
         final int N = pkg.requestedPermissions.size();
         for (int i=0; i<N; i++) {
             final String name = pkg.requestedPermissions.get(i);
-            final boolean required = pkg.requestedPermissionsRequired.get(i);
             final BasePermission bp = mSettings.mPermissions.get(name);
+
             if (DEBUG_INSTALL) {
-                if (gp != ps) {
-                    Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
-                }
+                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
             }
 
             if (bp == null || bp.packageSetting == null) {
@@ -6894,10 +6996,11 @@
             }
 
             final String perm = bp.name;
-            boolean allowed;
             boolean allowedSig = false;
-            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
-                // Keep track of app op permissions.
+            int grant = GRANT_DENIED;
+
+            // Keep track of app op permissions.
+            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
                 if (pkgs == null) {
                     pkgs = new ArraySet<>();
@@ -6905,65 +7008,106 @@
                 }
                 pkgs.add(pkg.packageName);
             }
+
             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
-            if (level == PermissionInfo.PROTECTION_NORMAL
-                    || level == PermissionInfo.PROTECTION_DANGEROUS) {
-                // We grant a normal or dangerous permission if any of the following
-                // are true:
-                // 1) The permission is required
-                // 2) The permission is optional, but was granted in the past
-                // 3) The permission is optional, but was requested by an
-                //    app in /system (not /data)
-                //
-                // Otherwise, reject the permission.
-                allowed = (required || origPermissions.contains(perm)
-                        || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
-            } else if (bp.packageSetting == null) {
-                // This permission is invalid; skip it.
-                allowed = false;
-            } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
-                allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
-                if (allowed) {
-                    allowedSig = true;
-                }
-            } else {
-                allowed = false;
+            switch (level) {
+                case PermissionInfo.PROTECTION_NORMAL: {
+                    // For all apps normal permissions are install time ones.
+                    grant = GRANT_INSTALL;
+                } break;
+
+                case PermissionInfo.PROTECTION_DANGEROUS: {
+                    if (!RUNTIME_PERMISSIONS_ENABLED
+                            || pkg.applicationInfo.targetSdkVersion
+                                    <= Build.VERSION_CODES.LOLLIPOP_MR1) {
+                        // For legacy apps dangerous permissions are install time ones.
+                        grant = GRANT_INSTALL;
+                    } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        // For modern system apps dangerous permissions are install time ones.
+                        grant = GRANT_INSTALL;
+                    } else {
+                        if (origPermissions.hasInstallPermission(bp.name)) {
+                            // For legacy apps that became modern, install becomes runtime.
+                            grant = GRANT_UPGRADE;
+                        } else if (replace) {
+                            // For upgraded modern apps keep runtime permissions unchanged.
+                            grant = GRANT_RUNTIME;
+                        }
+                    }
+                } break;
+
+                case PermissionInfo.PROTECTION_SIGNATURE: {
+                    // For all apps signature permissions are install time ones.
+                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
+                    if (allowedSig) {
+                        grant = GRANT_INSTALL;
+                    }
+                } break;
             }
+
             if (DEBUG_INSTALL) {
-                if (gp != ps) {
-                    Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
-                }
+                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
             }
-            if (allowed) {
+
+            if (grant != GRANT_DENIED) {
                 if (!isSystemApp(ps) && ps.permissionsFixed) {
                     // If this is an existing, non-system package, then
                     // we can't add any new permissions to it.
-                    if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
+                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
                         // Except...  if this is a permission that was added
                         // to the platform (note: need to only do this when
                         // updating the platform).
-                        allowed = isNewPlatformPermissionForPackage(perm, pkg);
+                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
+                            grant = GRANT_DENIED;
+                        }
                     }
                 }
-                if (allowed) {
-                    if (!gp.grantedPermissions.contains(perm)) {
-                        changedPermission = true;
-                        gp.grantedPermissions.add(perm);
-                        gp.gids = appendInts(gp.gids, bp.gids);
-                    } else if (!ps.haveGids) {
-                        gp.gids = appendInts(gp.gids, bp.gids);
-                    }
-                } else {
-                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
-                        Slog.w(TAG, "Not granting permission " + perm
-                                + " to package " + pkg.packageName
-                                + " because it was previously installed without");
-                    }
+
+                switch (grant) {
+                    case GRANT_INSTALL: {
+                        // Grant an install permission.
+                        if (permissionsState.grantInstallPermission(bp) !=
+                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                            changedPermission = true;
+                        }
+                    } break;
+
+                    case GRANT_RUNTIME: {
+                        // Grant previously granted runtime permissions.
+                        for (int userId : UserManagerService.getInstance().getUserIds()) {
+                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
+                                if (permissionsState.grantRuntimePermission(bp, userId) !=
+                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                                    changedPermission = true;
+                                }
+                            }
+                        }
+                    } break;
+
+                    case GRANT_UPGRADE: {
+                        // Grant runtime permissions for a previously held install permission.
+                        permissionsState.revokeInstallPermission(bp);
+                        for (int userId : UserManagerService.getInstance().getUserIds()) {
+                            if (permissionsState.grantRuntimePermission(bp, userId) !=
+                                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                                changedPermission = true;
+                            }
+                        }
+                    } break;
+
+                    default: {
+                        if (packageOfInterest == null
+                                || packageOfInterest.equals(pkg.packageName)) {
+                            Slog.w(TAG, "Not granting permission " + perm
+                                    + " to package " + pkg.packageName
+                                    + " because it was previously installed without");
+                        }
+                    } break;
                 }
             } else {
-                if (gp.grantedPermissions.remove(perm)) {
+                if (permissionsState.revokeInstallPermission(bp) !=
+                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
                     changedPermission = true;
-                    gp.gids = removeInts(gp.gids, bp.gids);
                     Slog.i(TAG, "Un-granting permission " + perm
                             + " from package " + pkg.packageName
                             + " (protectionLevel=" + bp.protectionLevel
@@ -6990,7 +7134,6 @@
             // changed.
             ps.permissionsFixed = true;
         }
-        ps.haveGids = true;
     }
 
     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
@@ -7011,7 +7154,7 @@
     }
 
     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
-                                          BasePermission bp, ArraySet<String> origPermissions) {
+            BasePermission bp, PermissionsState origPermissions) {
         boolean allowed;
         allowed = (compareSignatures(
                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
@@ -7026,10 +7169,7 @@
                 if (isUpdatedSystemApp(pkg)) {
                     final PackageSetting sysPs = mSettings
                             .getDisabledSystemPkgLPr(pkg.packageName);
-                    final GrantedPermissions origGp = sysPs.sharedUser != null
-                            ? sysPs.sharedUser : sysPs;
-
-                    if (origGp.grantedPermissions.contains(perm)) {
+                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
                         // If the original was granted this permission, we take
                         // that grant decision as read and propagate it to the
                         // update.
@@ -7063,7 +7203,7 @@
                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
             // For development permissions, a development permission
             // is granted only if it was already granted.
-            allowed = origPermissions.contains(perm);
+            allowed = origPermissions.hasInstallPermission(perm);
         }
         return allowed;
     }
@@ -10821,11 +10961,26 @@
                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
                     }
-                    if (deletedPs != null) {
-                        updatePermissionsLPw(deletedPs.name, null, 0);
-                        if (deletedPs.sharedUser != null) {
-                            // remove permissions associated with package
-                            mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
+                    updatePermissionsLPw(deletedPs.name, null, 0);
+                    if (deletedPs.sharedUser != null) {
+                        // Remove permissions associated with package. Since runtime
+                        // permissions are per user we have to kill the removed package
+                        // or packages running under the shared user of the removed
+                        // package if revoking the permissions requested only by the removed
+                        // package is successful and this causes a change in gids.
+                        for (int userId : UserManagerService.getInstance().getUserIds()) {
+                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
+                                    userId);
+                            if (userIdToKill == userId) {
+                                // If gids changed for this user, kill all affected packages.
+                                killSettingPackagesForUser(deletedPs, userIdToKill,
+                                        KILL_APP_REASON_GIDS_CHANGED);
+                            } else if (userIdToKill == UserHandle.USER_ALL) {
+                                // If gids changed for all users, kill them all - done.
+                                killSettingPackagesForUser(deletedPs, userIdToKill,
+                                        KILL_APP_REASON_GIDS_CHANGED);
+                                break;
+                            }
                         }
                     }
                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 06d842a..889164c 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -57,8 +57,10 @@
             + " " + name + "/" + appId + "}";
     }
 
-    public int[] getGids() {
-        return sharedUser != null ? sharedUser.gids : gids;
+    public PermissionsState getPermissionsState() {
+        return (sharedUser != null)
+                ? sharedUser.getPermissionsState()
+                : super.getPermissionsState();
     }
 
     public boolean isPrivileged() {
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 4b8ca42..9e8b3df 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -29,7 +29,7 @@
 /**
  * Settings base class for pending and resolved classes.
  */
-class PackageSettingBase extends GrantedPermissions {
+abstract class PackageSettingBase extends SettingBase {
     /**
      * Indicates the state of installation. Used by PackageManager to figure out
      * incomplete installations. Say a package is being installed (the state is
@@ -93,7 +93,6 @@
     PackageSignatures signatures = new PackageSignatures();
 
     boolean permissionsFixed;
-    boolean haveGids;
 
     PackageKeySetData keySetData = new PackageKeySetData();
 
@@ -147,7 +146,6 @@
         signatures = new PackageSignatures(base.signatures);
 
         permissionsFixed = base.permissionsFixed;
-        haveGids = base.haveGids;
         userState.clear();
         for (int i=0; i<base.userState.size(); i++) {
             userState.put(base.userState.keyAt(i),
@@ -160,7 +158,6 @@
         installerPackageName = base.installerPackageName;
 
         keySetData = new PackageKeySetData(base.keySetData);
-
     }
 
     void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
@@ -201,9 +198,7 @@
      * Make a shallow copy of this package settings.
      */
     public void copyFrom(PackageSettingBase base) {
-        grantedPermissions = base.grantedPermissions;
-        gids = base.gids;
-
+        getPermissionsState().copyFrom(base.getPermissionsState());
         primaryCpuAbiString = base.primaryCpuAbiString;
         secondaryCpuAbiString = base.secondaryCpuAbiString;
         cpuAbiOverrideString = base.cpuAbiOverrideString;
@@ -212,7 +207,6 @@
         lastUpdateTime = base.lastUpdateTime;
         signatures = base.signatures;
         permissionsFixed = base.permissionsFixed;
-        haveGids = base.haveGids;
         userState.clear();
         for (int i=0; i<base.userState.size(); i++) {
             userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
new file mode 100644
index 0000000..3e0e342
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * This class encapsulates the permissions for a package or a shared user.
+ * <p>
+ * There are two types of permissions: install (granted at installation)
+ * and runtime (granted at runtime). Install permissions are granted to
+ * all device users while runtime permissions are granted explicitly to
+ * specific users.
+ * </p>
+ * <p>
+ * The permissions are kept on a per device user basis. For example, an
+ * application may have some runtime permissions granted under the device
+ * owner but not granted under the secondary user.
+ * <p>
+ * This class is also responsible for keeping track of the Linux gids per
+ * user for a package or a shared user. The gids are computed as a set of
+ * the gids for all granted permissions' gids on a per user basis.
+ * </p>
+ */
+public final class PermissionsState {
+
+    /** The permission operation succeeded and no gids changed. */
+    public static final int PERMISSION_OPERATION_SUCCESS = 1;
+
+    /** The permission operation succeeded and gids changed. */
+    public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 2;
+
+    /** The permission operation failed. */
+    public static final int PERMISSION_OPERATION_FAILURE = 3;
+
+    private static final int[] USERS_ALL = {UserHandle.USER_ALL};
+
+    private static final int[] USERS_NONE = {};
+
+    private static final int[] NO_GIDS = {};
+
+    private ArrayMap<String, PermissionData> mPermissions;
+
+    private int[] mGlobalGids = NO_GIDS;
+
+    public PermissionsState() {
+        /* do nothing */
+    }
+
+    public PermissionsState(PermissionsState prototype) {
+        copyFrom(prototype);
+    }
+
+    /**
+     * Sets the global gids, applicable to all users.
+     *
+     * @param globalGids The global gids.
+     */
+    public void setGlobalGids(int[] globalGids) {
+        if (!ArrayUtils.isEmpty(globalGids)) {
+            mGlobalGids = Arrays.copyOf(globalGids, globalGids.length);
+        }
+    }
+
+    /**
+     * Initialized this instance from another one.
+     *
+     * @param other The other instance.
+     */
+    public void copyFrom(PermissionsState other) {
+        if (mPermissions != null) {
+            if (other.mPermissions == null) {
+                mPermissions = null;
+            } else {
+                mPermissions.clear();
+            }
+        }
+        if (other.mPermissions != null) {
+            if (mPermissions == null) {
+                mPermissions = new ArrayMap<>();
+            }
+            final int permissionCount = other.mPermissions.size();
+            for (int i = 0; i < permissionCount; i++) {
+                String name = other.mPermissions.keyAt(i);
+                PermissionData permissionData = other.mPermissions.valueAt(i);
+                mPermissions.put(name, new PermissionData(permissionData));
+            }
+        }
+
+        mGlobalGids = NO_GIDS;
+        if (other.mGlobalGids != NO_GIDS) {
+            mGlobalGids = Arrays.copyOf(other.mGlobalGids,
+                    other.mGlobalGids.length);
+        }
+    }
+
+    /**
+     * Grant an install permission.
+     *
+     * @param permission The permission to grant.
+     * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
+     *     or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
+     *     #PERMISSION_OPERATION_FAILURE}.
+     */
+    public int grantInstallPermission(BasePermission permission) {
+        return grantPermission(permission, UserHandle.USER_ALL);
+    }
+
+    /**
+     * Revoke an install permission.
+     *
+     * @param permission The permission to revoke.
+     * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
+     *     or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
+     *     #PERMISSION_OPERATION_FAILURE}.
+     */
+    public int revokeInstallPermission(BasePermission permission) {
+        return revokePermission(permission, UserHandle.USER_ALL);
+    }
+
+    /**
+     * Grant a runtime permission.
+     *
+     * @param permission The permission to grant.
+     * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
+     *     or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
+     *     #PERMISSION_OPERATION_FAILURE}.
+     */
+    public int grantRuntimePermission(BasePermission permission, int userId) {
+        return grantPermission(permission, userId);
+    }
+
+    /**
+     * Revoke a runtime permission for a given device user.
+     *
+     * @param permission The permission to revoke.
+     * @param userId The device user id.
+     * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
+     *     or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
+     *     #PERMISSION_OPERATION_FAILURE}.
+     */
+    public int revokeRuntimePermission(BasePermission permission, int userId) {
+        return revokePermission(permission, userId);
+    }
+
+    /**
+     * Gets whether this state has a given permission, regardless if
+     * it is install time or runtime one.
+     *
+     * @param name The permission name.
+     * @return Whether this state has the permission.
+     */
+    public boolean hasPermission(String name) {
+        return mPermissions != null && mPermissions.get(name) != null;
+    }
+
+    /**
+     * Gets whether this state has a given runtime permission for a
+     * given device user id.
+     *
+     * @param name The permission name.
+     * @param userId The device user id.
+     * @return Whether this state has the permission.
+     */
+    public boolean hasRuntimePermission(String name, int userId) {
+        return !hasInstallPermission(name) && hasPermission(name, userId);
+    }
+
+    /**
+     * Gets whether this state has a given install permission.
+     *
+     * @param name The permission name.
+     * @return Whether this state has the permission.
+     */
+    public boolean hasInstallPermission(String name) {
+        return hasPermission(name, UserHandle.USER_ALL);
+    }
+
+    /**
+     * Revokes a permission for all users regardless if it is an install or
+     * a runtime permission.
+     *
+     * @param permission The permission to revoke.
+     * @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
+     *     or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
+     *     #PERMISSION_OPERATION_FAILURE}.
+     */
+    public int revokePermission(BasePermission permission) {
+        if (!hasPermission(permission.name)) {
+            return PERMISSION_OPERATION_FAILURE;
+        }
+
+        int result = PERMISSION_OPERATION_SUCCESS;
+
+        PermissionData permissionData = mPermissions.get(permission.name);
+        if (permissionData.hasGids()) {
+            for (int userId : permissionData.getUserIds()) {
+                if (revokePermission(permission, userId)
+                        == PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
+                    result = PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
+                    break;
+                }
+            }
+        }
+
+        mPermissions.remove(permission.name);
+
+        return result;
+    }
+
+    /**
+     * Gets whether the state has a given permission for the specified
+     * user, regardless if this is an install or a runtime permission.
+     *
+     * @param name The permission name.
+     * @param userId The device user id.
+     * @return Whether the user has the permission.
+     */
+    public boolean hasPermission(String name, int userId) {
+        enforceValidUserId(userId);
+
+        if (mPermissions == null) {
+            return false;
+        }
+
+        PermissionData permissionData = mPermissions.get(name);
+        return permissionData != null && permissionData.hasUserId(userId);
+    }
+
+    /**
+     * Gets all permissions regardless if they are install or runtime.
+     *
+     * @return The permissions or an empty set.
+     */
+    public Set<String> getPermissions() {
+        if (mPermissions != null) {
+            return mPermissions.keySet();
+        }
+
+        return Collections.emptySet();
+    }
+
+    /**
+     * Gets all permissions for a given device user id regardless if they
+     * are install time or runtime permissions.
+     *
+     * @param userId The device user id.
+     * @return The permissions or an empty set.
+     */
+    public Set<String> getPermissions(int userId) {
+        enforceValidUserId(userId);
+
+        if (mPermissions == null) {
+            return Collections.emptySet();
+        }
+
+        Set<String> permissions = new ArraySet<>();
+
+        final int permissionCount = mPermissions.size();
+        for (int i = 0; i < permissionCount; i++) {
+            String permission = mPermissions.keyAt(i);
+            if (userId == UserHandle.USER_ALL) {
+                if (hasInstallPermission(permission)) {
+                    permissions.add(permission);
+                }
+            } else {
+                if (hasRuntimePermission(permission, userId)) {
+                    permissions.add(permission);
+                }
+            }
+        }
+
+        return  permissions;
+    }
+
+    /**
+     * Gets all runtime permissions.
+     *
+     * @return The permissions or an empty set.
+     */
+    public Set<String> getRuntimePermissions(int userId) {
+        return getPermissions(userId);
+    }
+
+    /**
+     * Gets all install permissions.
+     *
+     * @return The permissions or an empty set.
+     */
+    public Set<String> getInstallPermissions() {
+        return getPermissions(UserHandle.USER_ALL);
+    }
+
+    /**
+     * Compute the Linux gids for a given device user from the permissions
+     * granted to this user. Note that these are computed to avoid additional
+     * state as they are rarely accessed.
+     *
+     * @param userId The device user id.
+     * @return The gids for the device user.
+     */
+    public int[] computeGids(int userId) {
+        enforceValidUserId(userId);
+
+        int[] gids = mGlobalGids;
+
+        if (mPermissions != null) {
+            final int permissionCount = mPermissions.size();
+            for (int i = 0; i < permissionCount; i++) {
+                String permission = mPermissions.keyAt(i);
+                if (!hasPermission(permission, userId)) {
+                    continue;
+                }
+                PermissionData permissionData = mPermissions.valueAt(i);
+                final int[] permGids = permissionData.computeGids(userId);
+                if (permGids != NO_GIDS) {
+                    gids = appendInts(gids, permGids);
+                }
+            }
+        }
+
+        return gids;
+    }
+
+    /**
+     * Compute the Linux gids for all device users from the permissions
+     * granted to these users.
+     *
+     * @return The gids for all device users.
+     */
+    public int[] computeGids() {
+        int[] gids = mGlobalGids;
+
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            final int[] userGids = computeGids(userId);
+            gids = appendInts(gids, userGids);
+        }
+
+        return gids;
+    }
+
+    /**
+     * Resets the internal state of this object.
+     */
+    public void reset() {
+        mGlobalGids = NO_GIDS;
+        mPermissions = null;
+    }
+
+    private int grantPermission(BasePermission permission, int userId) {
+        if (hasPermission(permission.name, userId)) {
+            return PERMISSION_OPERATION_FAILURE;
+        }
+
+        final boolean hasGids = permission.hasGids();
+        final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;
+
+        if (mPermissions == null) {
+            mPermissions = new ArrayMap<>();
+        }
+
+        PermissionData permissionData = mPermissions.get(permission.name);
+        if (permissionData == null) {
+            permissionData = new PermissionData(permission);
+            mPermissions.put(permission.name, permissionData);
+        }
+
+        if (!permissionData.addUserId(userId)) {
+            return PERMISSION_OPERATION_FAILURE;
+        }
+
+        if (hasGids) {
+            final int[] newGids = computeGids(userId);
+            if (oldGids.length != newGids.length) {
+                return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
+            }
+        }
+
+        return PERMISSION_OPERATION_SUCCESS;
+    }
+
+    private int revokePermission(BasePermission permission, int userId) {
+        if (!hasPermission(permission.name, userId)) {
+            return PERMISSION_OPERATION_FAILURE;
+        }
+
+        final boolean hasGids = permission.hasGids();
+        final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;
+
+        PermissionData permissionData = mPermissions.get(permission.name);
+
+        if (!permissionData.removeUserId(userId)) {
+            return PERMISSION_OPERATION_FAILURE;
+        }
+
+        if (permissionData.getUserIds() == USERS_NONE) {
+            mPermissions.remove(permission.name);
+        }
+
+        if (mPermissions.isEmpty()) {
+            mPermissions = null;
+        }
+
+        if (hasGids) {
+            final int[] newGids = computeGids(userId);
+            if (oldGids.length != newGids.length) {
+                return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
+            }
+        }
+
+        return PERMISSION_OPERATION_SUCCESS;
+    }
+
+    private static int[] appendInts(int[] current, int[] added) {
+        if (current != null && added != null) {
+            for (int guid : added) {
+                current = ArrayUtils.appendInt(current, guid);
+            }
+        }
+        return current;
+    }
+
+    private static void enforceValidUserId(int userId) {
+        if (userId != UserHandle.USER_ALL && userId < 0) {
+            throw new IllegalArgumentException("Invalid userId:" + userId);
+        }
+    }
+
+    private static final class PermissionData {
+        private final BasePermission mPerm;
+        private int[] mUserIds = USERS_NONE;
+
+        public PermissionData(BasePermission perm) {
+            mPerm = perm;
+        }
+
+        public PermissionData(PermissionData other) {
+            this(other.mPerm);
+
+            if (other.mUserIds == USERS_ALL || other.mUserIds == USERS_NONE) {
+                mUserIds = other.mUserIds;
+            } else {
+                mUserIds = Arrays.copyOf(other.mUserIds, other.mUserIds.length);
+            }
+        }
+
+        public boolean hasGids() {
+            return mPerm.hasGids();
+        }
+
+        public int[] computeGids(int userId) {
+            return mPerm.computeGids(userId);
+        }
+
+        public int[] getUserIds() {
+            return mUserIds;
+        }
+
+        public boolean hasUserId(int userId) {
+            if (mUserIds == USERS_ALL) {
+                return true;
+            }
+
+            if (userId != UserHandle.USER_ALL) {
+                return ArrayUtils.contains(mUserIds, userId);
+            }
+
+            return false;
+        }
+
+        public boolean addUserId(int userId) {
+            if (hasUserId(userId)) {
+                return false;
+            }
+
+            if (userId == UserHandle.USER_ALL) {
+                mUserIds = USERS_ALL;
+                return true;
+            }
+
+            mUserIds = ArrayUtils.appendInt(mUserIds, userId);
+
+            return true;
+        }
+
+        public boolean removeUserId(int userId) {
+            if (!hasUserId(userId)) {
+                return false;
+            }
+
+            if (mUserIds == USERS_ALL) {
+                mUserIds = UserManagerService.getInstance().getUserIds();
+            }
+
+            mUserIds = ArrayUtils.removeInt(mUserIds, userId);
+
+            if (mUserIds.length == 0) {
+                mUserIds = USERS_NONE;
+            }
+
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/GrantedPermissions.java b/services/core/java/com/android/server/pm/SettingBase.java
similarity index 74%
rename from services/core/java/com/android/server/pm/GrantedPermissions.java
rename to services/core/java/com/android/server/pm/SettingBase.java
index e87546c..d350c09 100644
--- a/services/core/java/com/android/server/pm/GrantedPermissions.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -19,27 +19,26 @@
 import android.content.pm.ApplicationInfo;
 import android.util.ArraySet;
 
-class GrantedPermissions {
+abstract class SettingBase {
     int pkgFlags;
     int pkgPrivateFlags;
 
-    ArraySet<String> grantedPermissions = new ArraySet<String>();
+    private final PermissionsState mPermissionsState;
 
-    int[] gids;
-
-    GrantedPermissions(int pkgFlags, int pkgPrivateFlags) {
+    SettingBase(int pkgFlags, int pkgPrivateFlags) {
         setFlags(pkgFlags);
         setPrivateFlags(pkgPrivateFlags);
+        mPermissionsState = new PermissionsState();
     }
 
-    @SuppressWarnings("unchecked")
-    GrantedPermissions(GrantedPermissions base) {
+    SettingBase(SettingBase base) {
         pkgFlags = base.pkgFlags;
-        grantedPermissions = new ArraySet<>(base.grantedPermissions);
+        pkgPrivateFlags = base.pkgPrivateFlags;
+        mPermissionsState = new PermissionsState(base.mPermissionsState);
+    }
 
-        if (base.gids != null) {
-            gids = base.gids.clone();
-        }
+    public PermissionsState getPermissionsState() {
+        return mPermissionsState;
     }
 
     void setFlags(int pkgFlags) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b820d7e8..82aa74a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -25,6 +25,7 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.PACKAGE_INFO_GID;
 
+import android.content.Context;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ResolveInfo;
@@ -33,17 +34,27 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.FileUtils;
+import android.os.Handler;
+import android.os.Message;
 import android.os.PatternMatcher;
 import android.os.Process;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.AtomicFile;
 import android.util.LogPrinter;
 
+import android.util.SparseBooleanArray;
+import android.util.SparseLongArray;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.XmlUtils;
 import com.android.server.pm.PackageManagerService.DumpState;
 
+import java.io.FileNotFoundException;
 import java.util.Collection;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -51,7 +62,6 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
@@ -134,6 +144,8 @@
     private static final boolean DEBUG_STOPPED = false;
     private static final boolean DEBUG_MU = false;
 
+    private static final String RUNTIME_PERMISSIONS_FILE_NAME = "runtime-permissions.xml";
+
     private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
     private static final String ATTR_ENFORCEMENT = "enforcement";
 
@@ -142,6 +154,9 @@
     private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
     private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
     private static final String TAG_PACKAGE = "pkg";
+    private static final String TAG_SHARED_USER = "shared-user";
+    private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions";
+    private static final String TAG_PERMISSIONS = "perms";
     private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
             "persistent-preferred-activities";
     static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
@@ -161,6 +176,11 @@
     private static final String ATTR_INSTALLED = "inst";
     private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
 
+    private final Object mLock;
+    private final Context mContext;
+
+    private final RuntimePermissionPersistence mRuntimePermissionsPersistence;
+
     private final File mSettingsFilename;
     private final File mBackupSettingsFilename;
     private final File mPackageListFilename;
@@ -257,11 +277,16 @@
 
     public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
 
-    Settings(Context context) {
-        this(context, Environment.getDataDirectory());
+    Settings(Context context, Object lock) {
+        this(context, Environment.getDataDirectory(), lock);
     }
 
-    Settings(Context context, File dataDir) {
+    Settings(Context context, File dataDir, Object lock) {
+        mContext = context;
+        mLock = lock;
+
+        mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
+
         mSystemDir = new File(dataDir, "system");
         mSystemDir.mkdirs();
         FileUtils.setPermissions(mSystemDir.toString(),
@@ -460,7 +485,7 @@
                         bp.pendingInfo.packageName = newPkg;
                     }
                     bp.uid = 0;
-                    bp.gids = null;
+                    bp.setGids(null, false);
                 }
             }
         }
@@ -468,9 +493,9 @@
 
     private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
-            String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString,
-            int vc, int pkgFlags, int pkgPrivateFlags, UserHandle installUser, boolean add,
-            boolean allowInstall) {
+            String legacyNativeLibraryPathString, String primaryCpuAbiString,
+            String secondaryCpuAbiString, int vc, int pkgFlags, int pkgPrivateFlags,
+            UserHandle installUser, boolean add, boolean allowInstall) {
         PackageSetting p = mPackages.get(name);
         UserManagerService userManager = UserManagerService.getInstance();
         if (p != null) {
@@ -589,7 +614,7 @@
                         }
                         p.appId = dis.appId;
                         // Clone permissions
-                        p.grantedPermissions = new ArraySet<String>(dis.grantedPermissions);
+                        p.getPermissionsState().copyFrom(dis.getPermissionsState());
                         // Clone component info
                         List<UserInfo> users = getAllUsers();
                         if (users != null) {
@@ -732,45 +757,60 @@
      * not in use by other permissions of packages in the
      * shared user setting.
      */
-    void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
+    int updateSharedUserPermsLPw(PackageSetting deletedPs, int userId) {
         if ((deletedPs == null) || (deletedPs.pkg == null)) {
             Slog.i(PackageManagerService.TAG,
                     "Trying to update info for null package. Just ignoring");
-            return;
+            return UserHandle.USER_NULL;
         }
+
         // No sharedUserId
         if (deletedPs.sharedUser == null) {
-            return;
+            return UserHandle.USER_NULL;
         }
+
         SharedUserSetting sus = deletedPs.sharedUser;
+
         // Update permissions
         for (String eachPerm : deletedPs.pkg.requestedPermissions) {
-            boolean used = false;
-            if (!sus.grantedPermissions.contains(eachPerm)) {
+            BasePermission bp = mPermissions.get(eachPerm);
+            if (bp == null) {
                 continue;
             }
-            for (PackageSetting pkg:sus.packages) {
-                if (pkg.pkg != null &&
-                        !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
-                        pkg.pkg.requestedPermissions.contains(eachPerm)) {
+
+            // If no user has the permission, nothing to remove.
+            if (!sus.getPermissionsState().hasPermission(bp.name, userId)) {
+                 continue;
+            }
+
+            boolean used = false;
+
+            // Check if another package in the shared user needs the permission.
+            for (PackageSetting pkg : sus.packages) {
+                if (pkg.pkg != null
+                        && !pkg.pkg.packageName.equals(deletedPs.pkg.packageName)
+                        && pkg.pkg.requestedPermissions.contains(eachPerm)) {
                     used = true;
                     break;
                 }
             }
+
             if (!used) {
-                // can safely delete this permission from list
-                sus.grantedPermissions.remove(eachPerm);
+                // Try to revoke as an install permission which is for all users.
+                if (sus.getPermissionsState().revokeInstallPermission(bp) ==
+                        PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
+                    return UserHandle.USER_ALL;
+                }
+
+                // Try to revoke as an install permission which is per user.
+                if (sus.getPermissionsState().revokeRuntimePermission(bp, userId) ==
+                        PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
+                    return userId;
+                }
             }
         }
-        // Update gids
-        int newGids[] = globalGids;
-        for (String eachPerm : sus.grantedPermissions) {
-            BasePermission bp = mPermissions.get(eachPerm);
-            if (bp != null) {
-                newGids = PackageManagerService.appendInts(newGids, bp.gids);
-            }
-        }
-        sus.gids = newGids;
+
+        return UserHandle.USER_NULL;
     }
 
     int removePackageLPw(String name) {
@@ -895,7 +935,17 @@
     }
 
     private File getUserPackagesStateFile(int userId) {
-        return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml");
+        // TODO: Implement a cleaner solution when adding tests.
+        // This instead of Environment.getUserSystemDirectory(userId) to support testing.
+        File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
+        return new File(userDir, "package-restrictions.xml");
+    }
+
+    private File getUserRuntimePermissionsFile(int userId) {
+        // TODO: Implement a cleaner solution when adding tests.
+        // This instead of Environment.getUserSystemDirectory(userId) to support testing.
+        File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
+        return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
     }
 
     private File getUserPackagesStateBackupFile(int userId) {
@@ -912,15 +962,9 @@
         }
     }
 
-    void readAllUsersPackageRestrictionsLPr() {
-        List<UserInfo> users = getAllUsers();
-        if (users == null) {
-            readPackageRestrictionsLPr(0);
-            return;
-        }
-
-        for (UserInfo user : users) {
-            readPackageRestrictionsLPr(user.id);
+    void writeAllRuntimePermissionsLPr() {
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
         }
     }
 
@@ -1360,6 +1404,7 @@
                         }
                         serializer.endTag(null, TAG_DISABLED_COMPONENTS);
                     }
+
                     serializer.endTag(null, TAG_PACKAGE);
                 }
             }
@@ -1403,6 +1448,58 @@
         }
     }
 
+    void readInstallPermissionsLPr(XmlPullParser parser,
+            PermissionsState permissionsState) throws IOException, XmlPullParserException {
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG
+                || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG
+                    || type == XmlPullParser.TEXT) {
+                continue;
+            }
+            String tagName = parser.getName();
+            if (tagName.equals(TAG_ITEM)) {
+                String name = parser.getAttributeValue(null, ATTR_NAME);
+
+                BasePermission bp = mPermissions.get(name);
+                if (bp == null) {
+                    Slog.w(PackageManagerService.TAG, "Unknown permission: " + name);
+                    XmlUtils.skipCurrentTag(parser);
+                    continue;
+                }
+
+                if (permissionsState.grantInstallPermission(bp) ==
+                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                    Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
+                    XmlUtils.skipCurrentTag(parser);
+                }
+            } else {
+                Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    void writePermissionsLPr(XmlSerializer serializer, Set<String> permissions)
+            throws IOException {
+        if (permissions.isEmpty()) {
+            return;
+        }
+
+        serializer.startTag(null, TAG_PERMISSIONS);
+
+        for (String permission : permissions) {
+            serializer.startTag(null, TAG_ITEM);
+            serializer.attribute(null, ATTR_NAME, permission);
+            serializer.endTag(null, TAG_ITEM);
+        }
+
+        serializer.endTag(null, TAG_PERMISSIONS);
+    }
+
     // Note: assumed "stopped" field is already cleared in all packages.
     // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
     void readStoppedLPw() {
@@ -1594,13 +1691,7 @@
                 serializer.attribute(null, "userId",
                         Integer.toString(usr.userId));
                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
-                serializer.startTag(null, "perms");
-                for (String name : usr.grantedPermissions) {
-                    serializer.startTag(null, TAG_ITEM);
-                    serializer.attribute(null, ATTR_NAME, name);
-                    serializer.endTag(null, TAG_ITEM);
-                }
-                serializer.endTag(null, "perms");
+                writePermissionsLPr(serializer, usr.getPermissionsState().getInstallPermissions());
                 serializer.endTag(null, "shared-user");
             }
 
@@ -1614,7 +1705,7 @@
                     serializer.endTag(null, "cleaning-package");
                 }
             }
-            
+
             if (mRenamedPackages.size() > 0) {
                 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
                     serializer.startTag(null, "renamed-package");
@@ -1623,7 +1714,7 @@
                     serializer.endTag(null, "renamed-package");
                 }
             }
-            
+
             mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
 
             serializer.endTag(null, "packages");
@@ -1662,7 +1753,7 @@
                     final ApplicationInfo ai = pkg.pkg.applicationInfo;
                     final String dataPath = ai.dataDir;
                     final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-                    final int[] gids = pkg.getGids();
+                    final int[] gids = pkg.getPermissionsState().computeGids();
 
                     // Avoid any application that has a space in its path.
                     if (dataPath.indexOf(" ") >= 0)
@@ -1718,6 +1809,8 @@
             }
 
             writeAllUsersPackageRestrictionsLPr();
+
+            writeAllRuntimePermissionsLPr();
             return;
 
         } catch(XmlPullParserException e) {
@@ -1770,26 +1863,12 @@
         } else {
             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
         }
-        serializer.startTag(null, "perms");
+
+        // If this is a shared user, the permissions will be written there.
         if (pkg.sharedUser == null) {
-            // If this is a shared user, the permissions will
-            // be written there. We still need to write an
-            // empty permissions list so permissionsFixed will
-            // be set.
-            for (final String name : pkg.grantedPermissions) {
-                BasePermission bp = mPermissions.get(name);
-                if (bp != null) {
-                    // We only need to write signature or system permissions but
-                    // this wont
-                    // match the semantics of grantedPermissions. So write all
-                    // permissions.
-                    serializer.startTag(null, TAG_ITEM);
-                    serializer.attribute(null, ATTR_NAME, name);
-                    serializer.endTag(null, TAG_ITEM);
-                }
-            }
+            writePermissionsLPr(serializer, pkg.getPermissionsState().getInstallPermissions());
         }
-        serializer.endTag(null, "perms");
+
         serializer.endTag(null, "updated-package");
     }
 
@@ -1840,19 +1919,7 @@
         }
         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
         if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-            serializer.startTag(null, "perms");
-            if (pkg.sharedUser == null) {
-                // If this is a shared user, the permissions will
-                // be written there. We still need to write an
-                // empty permissions list so permissionsFixed will
-                // be set.
-                for (final String name : pkg.grantedPermissions) {
-                    serializer.startTag(null, TAG_ITEM);
-                    serializer.attribute(null, ATTR_NAME, name);
-                    serializer.endTag(null, TAG_ITEM);
-                }
-            }
-            serializer.endTag(null, "perms");
+            writePermissionsLPr(serializer, pkg.getPermissionsState().getInstallPermissions());
         }
 
         writeSigningKeySetsLPr(serializer, pkg.keySetData);
@@ -2161,9 +2228,11 @@
         } else {
             if (users == null) {
                 readPackageRestrictionsLPr(0);
+                mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER);
             } else {
                 for (UserInfo user : users) {
                     readPackageRestrictionsLPr(user.id);
+                    mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
                 }
             }
         }
@@ -2537,7 +2606,7 @@
                 final String ptype = parser.getAttributeValue(null, "type");
                 if (name != null && sourcePackage != null) {
                     final boolean dynamic = "dynamic".equals(ptype);
-                    final BasePermission bp = new BasePermission(name, sourcePackage,
+                    final BasePermission bp = new BasePermission(name.intern(), sourcePackage,
                             dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
                     bp.protectionLevel = readInt(parser, null, "protection",
                             PermissionInfo.PROTECTION_NORMAL);
@@ -2643,6 +2712,7 @@
             String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
             ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
         }
+
         int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -2651,9 +2721,8 @@
                 continue;
             }
 
-            String tagName = parser.getName();
-            if (tagName.equals("perms")) {
-                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
+            if (parser.getName().equals(TAG_PERMISSIONS)) {
+                readInstallPermissionsLPr(parser, ps.getPermissionsState());
             } else {
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "Unknown element under <updated-package>: " + parser.getName());
@@ -2711,7 +2780,7 @@
             if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
                 primaryCpuAbiString = legacyCpuAbiString;
             }
-;
+
             version = parser.getAttributeValue(null, "version");
             if (version != null) {
                 try {
@@ -2902,7 +2971,6 @@
                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
                 }
             }
-
             int outerDepth = parser.getDepth();
             int type;
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -2919,8 +2987,9 @@
                     readEnabledComponentsLPw(packageSetting, parser, 0);
                 } else if (tagName.equals("sigs")) {
                     packageSetting.signatures.readXml(parser, mPastSignatures);
-                } else if (tagName.equals("perms")) {
-                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
+                } else if (tagName.equals(TAG_PERMISSIONS)) {
+                    readInstallPermissionsLPr(parser,
+                            packageSetting.getPermissionsState());
                     packageSetting.permissionsFixed = true;
                 } else if (tagName.equals("proper-signing-keyset")) {
                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
@@ -3039,7 +3108,6 @@
                     "Error in package manager settings: package " + name + " has bad userId "
                             + idStr + " at " + parser.getPositionDescription());
         }
-        ;
 
         if (su != null) {
             int outerDepth = parser.getDepth();
@@ -3054,47 +3122,18 @@
                 if (tagName.equals("sigs")) {
                     su.signatures.readXml(parser, mPastSignatures);
                 } else if (tagName.equals("perms")) {
-                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
+                    readInstallPermissionsLPr(parser, su.getPermissionsState());
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Unknown element under <shared-user>: " + parser.getName());
                     XmlUtils.skipCurrentTag(parser);
                 }
             }
-
         } else {
             XmlUtils.skipCurrentTag(parser);
         }
     }
 
-    private void readGrantedPermissionsLPw(XmlPullParser parser, ArraySet<String> outPerms)
-            throws IOException, XmlPullParserException {
-        int outerDepth = parser.getDepth();
-        int type;
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                continue;
-            }
-
-            String tagName = parser.getName();
-            if (tagName.equals(TAG_ITEM)) {
-                String name = parser.getAttributeValue(null, ATTR_NAME);
-                if (name != null) {
-                    outPerms.add(name.intern());
-                } else {
-                    PackageManagerService.reportSettingsProblem(Log.WARN,
-                            "Error in package manager settings: <perms> has" + " no name at "
-                                    + parser.getPositionDescription());
-                }
-            } else {
-                PackageManagerService.reportSettingsProblem(Log.WARN,
-                        "Unknown element under <perms>: " + parser.getName());
-            }
-            XmlUtils.skipCurrentTag(parser);
-        }
-    }
-
     void createNewUserLILPw(PackageManagerService service, Installer installer,
             int userHandle, File path) {
         path.mkdir();
@@ -3126,6 +3165,8 @@
         file = getUserPackagesStateBackupFile(userId);
         file.delete();
         removeCrossProfileIntentFiltersLPw(userId);
+
+        mRuntimePermissionsPersistence.onUserRemoved(userId);
     }
 
     void removeCrossProfileIntentFiltersLPw(int userId) {
@@ -3317,7 +3358,7 @@
         return null;
     }
 
-    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
+    static void printFlags(PrintWriter pw, int val, Object[] spec) {
         pw.print("[ ");
         for (int i=0; i<spec.length; i+=2) {
             int mask = (Integer)spec[i];
@@ -3414,8 +3455,8 @@
             pw.println(ps.name);
         }
 
-        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
-                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
+        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
+
         if (ps.sharedUser != null) {
             pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
         }
@@ -3525,10 +3566,15 @@
         }
         pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
         pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
-                pw.print(" haveGids="); pw.print(ps.haveGids);
                 pw.print(" installStatus="); pw.println(ps.installStatus);
         pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
                 pw.println();
+
+        if (ps.sharedUser == null) {
+            PermissionsState permissionsState = ps.getPermissionsState();
+            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionsState);
+        }
+
         for (UserInfo user : users) {
             pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
             pw.print(" installed=");
@@ -3546,6 +3592,14 @@
                 pw.print(prefix); pw.print("    lastDisabledCaller: ");
                         pw.println(lastDisabledAppCaller);
             }
+
+            if (ps.sharedUser == null) {
+                PermissionsState permissionsState = ps.getPermissionsState();
+                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
+                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionsState
+                        .getRuntimePermissions(user.id));
+            }
+
             ArraySet<String> cmp = ps.getDisabledComponents(user.id);
             if (cmp != null && cmp.size() > 0) {
                 pw.print(prefix); pw.println("    disabledComponents:");
@@ -3561,12 +3615,6 @@
                 }
             }
         }
-        if (ps.grantedPermissions.size() > 0) {
-            pw.print(prefix); pw.println("  grantedPermissions:");
-            for (String s : ps.grantedPermissions) {
-                pw.print(prefix); pw.print("    "); pw.println(s);
-            }
-        }
     }
 
     void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
@@ -3652,7 +3700,8 @@
                     pw.println("):");
             pw.print("    sourcePackage="); pw.println(p.sourcePackage);
             pw.print("    uid="); pw.print(p.uid);
-                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
+                    pw.print(" gids="); pw.print(Arrays.toString(
+                            p.computeGids(UserHandle.USER_OWNER)));
                     pw.print(" type="); pw.print(p.type);
                     pw.print(" prot=");
                     pw.println(PermissionInfo.protectionToString(p.protectionLevel));
@@ -3688,14 +3737,21 @@
                 pw.print("] (");
                 pw.print(Integer.toHexString(System.identityHashCode(su)));
                         pw.println("):");
-                pw.print("    userId=");
-                pw.print(su.userId);
-                pw.print(" gids=");
-                pw.println(PackageManagerService.arrayToString(su.gids));
-                pw.println("    grantedPermissions:");
-                for (String s : su.grantedPermissions) {
-                    pw.print("      ");
-                    pw.println(s);
+
+                String prefix = "    ";
+                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
+
+                PermissionsState permissionsState = su.getPermissionsState();
+                dumpInstallPermissionsLPr(pw, prefix, permissionsState);
+
+                for (int userId : UserManagerService.getInstance().getUserIds()) {
+                    final int[] gids = permissionsState.computeGids(userId);
+                    Set<String> permissions = permissionsState.getRuntimePermissions(userId);
+                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
+                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
+                        dumpGidsLPr(pw, prefix + "  ", gids);
+                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissions);
+                    }
                 }
             } else {
                 pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
@@ -3730,4 +3786,373 @@
             pw.print("]");
         }
     }
+
+    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
+        if (!ArrayUtils.isEmpty(gids)) {
+            pw.print(prefix); pw.print("gids="); pw.println(
+                    PackageManagerService.arrayToString(gids));
+        }
+    }
+
+    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, Set<String> permissions) {
+        if (!permissions.isEmpty()) {
+            pw.print(prefix); pw.println("runtime permissions:");
+            for (String permission : permissions) {
+                pw.print(prefix); pw.print("  "); pw.println(permission);
+            }
+        }
+    }
+
+    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix,
+            PermissionsState permissionsState) {
+        Set<String> permissions = permissionsState.getInstallPermissions();
+        if (!permissions.isEmpty()) {
+            pw.print(prefix); pw.println("install permissions:");
+            for (String permission : permissions) {
+                pw.print(prefix); pw.print("  "); pw.println(permission);
+            }
+        }
+    }
+
+    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
+        if (sync) {
+            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
+        } else {
+            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
+        }
+    }
+
+    private final class RuntimePermissionPersistence {
+        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
+
+        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
+
+        private final Handler mHandler = new MyHandler();
+
+        private final Object mLock;
+
+        @GuardedBy("mLock")
+        private SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
+
+        @GuardedBy("mLock")
+        private SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
+
+        public RuntimePermissionPersistence(Object lock) {
+            mLock = lock;
+        }
+
+        public void writePermissionsForUserSyncLPr(int userId) {
+            mHandler.removeMessages(userId);
+            writePermissionsSync(userId);
+        }
+
+        public void writePermissionsForUserAsyncLPr(int userId) {
+            final long currentTimeMillis = SystemClock.uptimeMillis();
+
+            if (mWriteScheduled.get(userId)) {
+                mHandler.removeMessages(userId);
+
+                // If enough time passed, write without holding off anymore.
+                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
+                        .get(userId);
+                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
+                        - lastNotWrittenMutationTimeMillis;
+                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
+                    mHandler.obtainMessage(userId).sendToTarget();
+                    return;
+                }
+
+                // Hold off a bit more as settings are frequently changing.
+                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
+                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
+                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
+                        maxDelayMillis);
+
+                Message message = mHandler.obtainMessage(userId);
+                mHandler.sendMessageDelayed(message, writeDelayMillis);
+            } else {
+                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
+                Message message = mHandler.obtainMessage(userId);
+                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
+                mWriteScheduled.put(userId, true);
+            }
+        }
+
+        private void writePermissionsSync(int userId) {
+            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
+
+            ArrayMap<String, Set<String>> permissionsForPackage = new ArrayMap<>();
+            ArrayMap<String, Set<String>> permissionsForSharedUser = new ArrayMap<>();
+
+            synchronized (mLock) {
+                mWriteScheduled.delete(userId);
+
+                final int packageCount = mPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    String packageName = mPackages.keyAt(i);
+                    PackageSetting packageSetting = mPackages.valueAt(i);
+                    if (packageSetting.sharedUser == null) {
+                        PermissionsState permissionsState = packageSetting.getPermissionsState();
+                        Set<String> permissions = permissionsState.getRuntimePermissions(userId);
+                        if (!permissions.isEmpty()) {
+                            permissionsForPackage.put(packageName, permissions);
+                        }
+                    }
+                }
+
+                final int sharedUserCount = mSharedUsers.size();
+                for (int i = 0; i < sharedUserCount; i++) {
+                    String sharedUserName = mSharedUsers.keyAt(i);
+                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
+                    PermissionsState permissionsState = sharedUser.getPermissionsState();
+                    Set<String> permissions = permissionsState.getRuntimePermissions(userId);
+                    if (!permissions.isEmpty()) {
+                        permissionsForSharedUser.put(sharedUserName, permissions);
+                    }
+                }
+            }
+
+            FileOutputStream out = null;
+            try {
+                out = destination.startWrite();
+
+                XmlSerializer serializer = Xml.newSerializer();
+                serializer.setOutput(out, "utf-8");
+                serializer.setFeature(
+                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+                serializer.startDocument(null, true);
+                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
+
+                final int packageCount = permissionsForPackage.size();
+                for (int i = 0; i < packageCount; i++) {
+                    String packageName = permissionsForPackage.keyAt(i);
+                    Set<String> permissions = permissionsForPackage.valueAt(i);
+                    serializer.startTag(null, TAG_PACKAGE);
+                    serializer.attribute(null, ATTR_NAME, packageName);
+                    writePermissions(serializer, permissions);
+                    serializer.endTag(null, TAG_PACKAGE);
+                }
+
+                final int sharedUserCount = permissionsForSharedUser.size();
+                for (int i = 0; i < sharedUserCount; i++) {
+                    String packageName = permissionsForSharedUser.keyAt(i);
+                    Set<String> permissions = permissionsForSharedUser.valueAt(i);
+                    serializer.startTag(null, TAG_SHARED_USER);
+                    serializer.attribute(null, ATTR_NAME, packageName);
+                    writePermissions(serializer, permissions);
+                    serializer.endTag(null, TAG_SHARED_USER);
+                }
+
+                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
+                serializer.endDocument();
+                destination.finishWrite(out);
+            } catch (IOException e) {
+                Slog.wtf(PackageManagerService.TAG,
+                        "Failed to write settings, restoring backup", e);
+                destination.failWrite(out);
+            } finally {
+                IoUtils.closeQuietly(out);
+            }
+        }
+
+        private void onUserRemoved(int userId) {
+            // Make sure we do not
+            mHandler.removeMessages(userId);
+
+            for (SettingBase sb : mPackages.values()) {
+                revokeRuntimePermissions(sb, userId);
+            }
+
+            for (SettingBase sb : mSharedUsers.values()) {
+                revokeRuntimePermissions(sb, userId);
+            }
+        }
+
+        private void revokeRuntimePermissions(SettingBase sb, int userId) {
+            PermissionsState permissionsState = sb.getPermissionsState();
+            for (String permission : permissionsState.getRuntimePermissions(userId)) {
+                BasePermission bp = mPermissions.get(permission);
+                if (bp != null) {
+                    permissionsState.revokeRuntimePermission(bp, userId);
+                }
+            }
+        }
+
+        public void readStateForUserSyncLPr(int userId) {
+            File permissionsFile = getUserRuntimePermissionsFile(userId);
+            if (!permissionsFile.exists()) {
+                return;
+            }
+
+            FileInputStream in;
+            try {
+                in = new FileInputStream(permissionsFile);
+            } catch (FileNotFoundException fnfe) {
+                Slog.i(PackageManagerService.TAG, "No permissions state");
+                return;
+            }
+
+            try {
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(in, null);
+                parseRuntimePermissionsLPr(parser, userId);
+            } catch (XmlPullParserException | IOException ise) {
+                throw new IllegalStateException("Failed parsing permissions file: "
+                        + permissionsFile , ise);
+            } finally {
+                IoUtils.closeQuietly(in);
+            }
+        }
+
+        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
+                throws IOException, XmlPullParserException {
+            parser.next();
+            skipEmptyTextTags(parser);
+            if (!accept(parser, XmlPullParser.START_TAG, TAG_RUNTIME_PERMISSIONS)) {
+                return;
+            }
+
+            parser.next();
+
+            while (parsePackageLPr(parser, userId)
+                    || parseSharedUserLPr(parser, userId)) {
+                parser.next();
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_RUNTIME_PERMISSIONS);
+        }
+
+        private boolean parsePackageLPr(XmlPullParser parser, int userId)
+                throws IOException, XmlPullParserException {
+            skipEmptyTextTags(parser);
+            if (!accept(parser, XmlPullParser.START_TAG, TAG_PACKAGE)) {
+                return false;
+            }
+
+            String name = parser.getAttributeValue(null, ATTR_NAME);
+
+            parser.next();
+
+            PackageSetting ps = mPackages.get(name);
+            if (ps != null) {
+                while (parsePermissionLPr(parser, ps.getPermissionsState(), userId)) {
+                    parser.next();
+                }
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_PACKAGE);
+
+            return true;
+        }
+
+        private boolean parseSharedUserLPr(XmlPullParser parser, int userId)
+                throws IOException, XmlPullParserException {
+            skipEmptyTextTags(parser);
+            if (!accept(parser, XmlPullParser.START_TAG, TAG_SHARED_USER)) {
+                return false;
+            }
+
+            String name = parser.getAttributeValue(null, ATTR_NAME);
+
+            parser.next();
+
+            SharedUserSetting sus = mSharedUsers.get(name);
+            if (sus != null) {
+                while (parsePermissionLPr(parser, sus.getPermissionsState(), userId)) {
+                    parser.next();
+                }
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_SHARED_USER);
+
+            return true;
+        }
+
+        private boolean parsePermissionLPr(XmlPullParser parser, PermissionsState permissionsState,
+                int userId) throws IOException, XmlPullParserException {
+            skipEmptyTextTags(parser);
+            if (!accept(parser, XmlPullParser.START_TAG, TAG_ITEM)) {
+                return false;
+            }
+
+            String name = parser.getAttributeValue(null, ATTR_NAME);
+
+            parser.next();
+
+            BasePermission bp = mPermissions.get(name);
+            if (bp != null) {
+                if (permissionsState.grantRuntimePermission(bp, userId) ==
+                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
+                    Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name);
+                }
+            } else {
+                Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_ITEM);
+
+            return true;
+        }
+
+        private void expect(XmlPullParser parser, int type, String tag)
+                throws IOException, XmlPullParserException {
+            if (!accept(parser, type, tag)) {
+                throw new XmlPullParserException("Expected event: " + type
+                        + " and tag: " + tag + " but got event: " + parser.getEventType()
+                        + " and tag:" + parser.getName());
+            }
+        }
+
+        private void skipEmptyTextTags(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+            while (accept(parser, XmlPullParser.TEXT, null)
+                    && parser.isWhitespace()) {
+                parser.next();
+            }
+        }
+
+        private boolean accept(XmlPullParser parser, int type, String tag)
+                throws IOException, XmlPullParserException {
+            if (parser.getEventType() != type) {
+                return false;
+            }
+            if (tag != null) {
+                if (!tag.equals(parser.getName())) {
+                    return false;
+                }
+            } else if (parser.getName() != null) {
+                return false;
+            }
+            return true;
+        }
+
+        private void writePermissions(XmlSerializer serializer, Set<String> permissions)
+                throws IOException {
+            for (String permission : permissions) {
+                serializer.startTag(null, TAG_ITEM);
+                serializer.attribute(null, ATTR_NAME, permission);
+                serializer.endTag(null, TAG_ITEM);
+            }
+        }
+
+        private final class MyHandler extends Handler {
+            public MyHandler() {
+                super(BackgroundThread.getHandler().getLooper());
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                final int userId = message.what;
+                Runnable callback = (Runnable) message.obj;
+                writePermissionsSync(userId);
+                if (callback != null) {
+                    callback.run();
+                }
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index d95739c..06e020a 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -21,7 +21,7 @@
 /**
  * Settings data for a particular shared user ID we know about.
  */
-final class SharedUserSetting extends GrantedPermissions {
+final class SharedUserSetting extends SettingBase {
     final String name;
 
     int userId;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 930ef9a..be6550c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4025,7 +4025,7 @@
     }
 
     private void offsetInputMethodWindowLw(WindowState win) {
-        int top = win.getDisplayFrameLw().top;
+        int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
         top += win.getGivenContentInsetsLw().top;
         if (mContentBottom > top) {
             mContentBottom = top;
@@ -4044,7 +4044,7 @@
     }
 
     private void offsetVoiceInputWindowLw(WindowState win) {
-        int top = win.getDisplayFrameLw().top;
+        int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
         top += win.getGivenContentInsetsLw().top;
         if (mVoiceContentBottom > top) {
             mVoiceContentBottom = top;
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index c09ea5c..e385be3 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -140,10 +140,9 @@
     }
 
     /**
-     * @param layer The new layer value.
-     * @param inTransaction Whether the call is made within a surface transaction.
+     * NOTE: Must be called with Surface transaction open.
      */
-    void adjustSurface(int layer, boolean inTransaction) {
+    private void adjustBounds() {
         final int dw, dh;
         final float xPos, yPos;
         if (!mStack.isFullscreen()) {
@@ -163,29 +162,24 @@
             yPos = -1 * dh / 6;
         }
 
-        try {
-            if (!inTransaction) {
-                SurfaceControl.openTransaction();
-            }
-            mDimSurface.setPosition(xPos, yPos);
-            mDimSurface.setSize(dw, dh);
-            mDimSurface.setLayer(layer);
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Failure setting size or layer", e);
-        } finally {
-            if (!inTransaction) {
-                SurfaceControl.closeTransaction();
-            }
-        }
+        mDimSurface.setPosition(xPos, yPos);
+        mDimSurface.setSize(dw, dh);
+
         mLastBounds.set(mBounds);
-        mLayer = layer;
     }
 
-    // Assumes that surface transactions are currently closed.
+    /** @param bounds The new bounds to set */
     void setBounds(Rect bounds) {
         mBounds.set(bounds);
         if (isDimming() && !mLastBounds.equals(bounds)) {
-            adjustSurface(mLayer, false);
+            try {
+                SurfaceControl.openTransaction();
+                adjustBounds();
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Failure setting size", e);
+            } finally {
+                SurfaceControl.closeTransaction();
+            }
         }
     }
 
@@ -224,9 +218,10 @@
             return;
         }
 
-        if (!mLastBounds.equals(mBounds) || mLayer != layer) {
-            adjustSurface(layer, true);
+        if (!mLastBounds.equals(mBounds)) {
+            adjustBounds();
         }
+        setLayer(layer);
 
         long curTime = SystemClock.uptimeMillis();
         final boolean animating = isAnimating();
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 6d09f55..b61a6f7 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -373,10 +373,8 @@
             mService.requestTraversalLocked();
         }
 
-        mAnimationBackgroundSurface.destroySurface();
-        mAnimationBackgroundSurface = null;
-        mDimLayer.destroySurface();
-        mDimLayer = null;
+        close();
+
         mDisplayContent = null;
     }
 
@@ -501,8 +499,14 @@
     }
 
     void close() {
-        mDimLayer.mDimSurface.destroy();
-        mAnimationBackgroundSurface.mDimSurface.destroy();
+        if (mAnimationBackgroundSurface != null) {
+            mAnimationBackgroundSurface.destroySurface();
+            mAnimationBackgroundSurface = null;
+        }
+        if (mDimLayer != null) {
+            mDimLayer.destroySurface();
+            mDimLayer = null;
+        }
     }
 
     public void dump(String prefix, PrintWriter pw) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4c80b07..1dc027a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -507,6 +507,7 @@
     boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
     int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+    int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 
     int mLayoutSeq = 0;
 
@@ -3115,6 +3116,10 @@
                 }
                 winAnimator.mEnteringAnimation = true;
                 if (toBeDisplayed) {
+                    if ((win.mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
+                            == SOFT_INPUT_ADJUST_RESIZE) {
+                        win.mLayoutNeeded = true;
+                    }
                     if (win.isDrawnLw() && okToDisplay()) {
                         winAnimator.applyEnterAnimationLocked();
                     }
@@ -3700,41 +3705,70 @@
         }
     }
 
-    public int getOrientationFromWindowsLocked() {
-        if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
-            // If the display is frozen, some activities may be in the middle
-            // of restarting, and thus have removed their old window.  If the
-            // window has the flag to hide the lock screen, then the lock screen
-            // can re-appear and inflict its own orientation on us.  Keep the
-            // orientation stable until this all settles down.
-            return mLastWindowForcedOrientation;
+    public int getOrientationLocked() {
+        if (mDisplayFrozen) {
+            if (mLastWindowForcedOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
+                if (DEBUG_ORIENTATION) Slog.v(TAG, "Display is frozen, return "
+                        + mLastWindowForcedOrientation);
+                // If the display is frozen, some activities may be in the middle
+                // of restarting, and thus have removed their old window.  If the
+                // window has the flag to hide the lock screen, then the lock screen
+                // can re-appear and inflict its own orientation on us.  Keep the
+                // orientation stable until this all settles down.
+                return mLastWindowForcedOrientation;
+            }
+        } else {
+            // TODO(multidisplay): Change to the correct display.
+            final WindowList windows = getDefaultWindowListLocked();
+            int pos = windows.size() - 1;
+            while (pos >= 0) {
+                WindowState win = windows.get(pos);
+                pos--;
+                if (win.mAppToken != null) {
+                    // We hit an application window. so the orientation will be determined by the
+                    // app window. No point in continuing further.
+                    break;
+                }
+                if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
+                    continue;
+                }
+                int req = win.mAttrs.screenOrientation;
+                if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
+                        (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
+                    continue;
+                }
+
+                if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
+                if (mPolicy.isKeyguardHostWindow(win.mAttrs)) {
+                    mLastKeyguardForcedOrientation = req;
+                }
+                return (mLastWindowForcedOrientation = req);
+            }
+            mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+            if (mPolicy.isKeyguardLocked()) {
+                // The screen is locked and no top system window is requesting an orientation.
+                // Return either the orientation of the show-when-locked app (if there is any) or
+                // the orientation of the keyguard. No point in searching from the rest of apps.
+                WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
+                AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
+                        null : winShowWhenLocked.mAppToken;
+                if (appShowWhenLocked != null) {
+                    int req = appShowWhenLocked.requestedOrientation;
+                    if (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+                        req = mLastKeyguardForcedOrientation;
+                    }
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + appShowWhenLocked
+                            + " -- show when locked, return " + req);
+                    return req;
+                }
+                if (DEBUG_ORIENTATION) Slog.v(TAG,
+                        "No one is requesting an orientation when the screen is locked");
+                return mLastKeyguardForcedOrientation;
+            }
         }
 
-        // TODO(multidisplay): Change to the correct display.
-        final WindowList windows = getDefaultWindowListLocked();
-        for (int pos = windows.size() - 1; pos >= 0; --pos) {
-            WindowState win = windows.get(pos);
-            if (win.mAppToken != null) {
-                // We hit an application window. so the orientation will be determined by the
-                // app window. No point in continuing further.
-                return (mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
-            }
-            if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
-                continue;
-            }
-            int req = win.mAttrs.screenOrientation;
-            if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
-                    (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
-                continue;
-            }
-
-            if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
-            return (mLastWindowForcedOrientation = req);
-        }
-        return (mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
-    }
-
-    public int getOrientationFromAppTokensLocked() {
+        // Top system windows are not requesting an orientation. Start searching from apps.
         int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
         boolean findingBehind = false;
         boolean lastFullscreen = false;
@@ -3804,8 +3838,11 @@
                 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
             }
         }
-        if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
-        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+        if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation, return "
+                + mForcedAppOrientation);
+        // The next app has not been requested to be visible, so we keep the current orientation
+        // to prevent freezing/unfreezing the display too early.
+        return mForcedAppOrientation;
     }
 
     @Override
@@ -3887,11 +3924,7 @@
     boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
         long ident = Binder.clearCallingIdentity();
         try {
-            int req = getOrientationFromWindowsLocked();
-            if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
-                req = getOrientationFromAppTokensLocked();
-            }
-
+            int req = getOrientationLocked();
             if (req != mForcedAppOrientation) {
                 mForcedAppOrientation = req;
                 //send a message to Policy indicating orientation change to take
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ed55c56..ae2c54b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -39,6 +39,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.storage.IMountService;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
@@ -131,6 +132,8 @@
             "com.android.server.ethernet.EthernetService";
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
             "com.android.server.job.JobSchedulerService";
+    private static final String MOUNT_SERVICE_CLASS =
+            "com.android.server.MountService$Lifecycle";
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
     private final int mFactoryTestMode;
@@ -384,7 +387,7 @@
         ContentService contentService = null;
         VibratorService vibrator = null;
         IAlarmManager alarm = null;
-        MountService mountService = null;
+        IMountService mountService = null;
         NetworkManagementService networkManagement = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
@@ -552,15 +555,19 @@
                      * NotificationManagerService is dependant on MountService,
                      * (for media / usb notifications) so we must start MountService first.
                      */
-                    Slog.i(TAG, "Mount Service");
-                    mountService = new MountService(context);
-                    ServiceManager.addService("mount", mountService);
+                    mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
+                    mountService = IMountService.Stub.asInterface(
+                            ServiceManager.getService("mount"));
                 } catch (Throwable e) {
                     reportWtf("starting Mount Service", e);
                 }
             }
         }
 
+        // We start this here so that we update our configuration to set watch or television
+        // as appropriate.
+        mSystemServiceManager.startService(UiModeManagerService.class);
+
         try {
             mPackageManagerService.performBootDexOpt();
         } catch (Throwable e) {
@@ -711,7 +718,10 @@
              * first before continuing.
              */
             if (mountService != null && !mOnlyCore) {
-                mountService.waitForAsecScan();
+                try {
+                    mountService.waitForAsecScan();
+                } catch (RemoteException ignored) {
+                }
             }
 
             try {
@@ -837,8 +847,6 @@
 
             mSystemServiceManager.startService(TwilightService.class);
 
-            mSystemServiceManager.startService(UiModeManagerService.class);
-
             mSystemServiceManager.startService(JobSchedulerService.class);
 
             if (!disableNonCoreServices) {
@@ -1039,7 +1047,6 @@
         }
 
         // These are needed to propagate to the runnable below.
-        final MountService mountServiceF = mountService;
         final NetworkManagementService networkManagementF = networkManagement;
         final NetworkStatsService networkStatsF = networkStats;
         final NetworkPolicyManagerService networkPolicyF = networkPolicy;
@@ -1087,11 +1094,6 @@
                     reportWtf("starting System UI", e);
                 }
                 try {
-                    if (mountServiceF != null) mountServiceF.systemReady();
-                } catch (Throwable e) {
-                    reportWtf("making Mount Service ready", e);
-                }
-                try {
                     if (networkScoreF != null) networkScoreF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making Network Score Service ready", e);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index b631331..4dc1131 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -32,7 +32,6 @@
 import java.io.IOException;
 
 public class PackageManagerSettingsTests extends AndroidTestCase {
-
     private static final String PACKAGE_NAME_2 = "com.google.app2";
     private static final String PACKAGE_NAME_3 = "com.android.app3";
     private static final String PACKAGE_NAME_1 = "com.google.app1";
@@ -56,7 +55,7 @@
         writeFile(new File(getContext().getFilesDir(), "system/packages.xml"),
                 ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<packages>"
-                + "<last-platform-version internal=\"15\" external=\"0\" />"
+                + "<last-platform-version internal=\"15\" external=\"0\" fingerprint=\"foo\" />"
                 + "<permission-trees>"
                 + "<item name=\"com.google.android.permtree\" package=\"com.google.android.permpackage\" />"
                 + "</permission-trees>"
@@ -110,28 +109,32 @@
                 .getBytes());
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    private void deleteSystemFolder() {
+        File systemFolder = new File(getContext().getFilesDir(), "system");
+        deleteFolder(systemFolder);
+    }
+
+    private static void deleteFolder(File folder) {
+        File[] files = folder.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                deleteFolder(file);
+            }
+        }
+        folder.delete();
     }
 
     private void writeOldFiles() {
+        deleteSystemFolder();
         writePackagesXml();
         writeStoppedPackagesXml();
         writePackagesList();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
     public void testSettingsReadOld() {
-        // Debug.waitForDebugger();
-
         // Write the package files and make sure they're parsed properly the first time
         writeOldFiles();
-        Settings settings = new Settings(getContext(), getContext().getFilesDir());
+        Settings settings = new Settings(getContext(), getContext().getFilesDir(), new Object());
         assertEquals(true, settings.readLPw(null, null, 0, false));
         assertNotNull(settings.peekPackageLPr(PACKAGE_NAME_3));
         assertNotNull(settings.peekPackageLPr(PACKAGE_NAME_1));
@@ -149,11 +152,12 @@
     public void testNewPackageRestrictionsFile() {
         // Write the package files and make sure they're parsed properly the first time
         writeOldFiles();
-        Settings settings = new Settings(getContext(), getContext().getFilesDir());
+        Settings settings = new Settings(getContext(), getContext().getFilesDir(), new Object());
         assertEquals(true, settings.readLPw(null, null, 0, false));
+        settings.writeLPr();
 
         // Create Settings again to make it read from the new files
-        settings = new Settings(getContext(), getContext().getFilesDir());
+        settings = new Settings(getContext(), getContext().getFilesDir(), new Object());
         assertEquals(true, settings.readLPw(null, null, 0, false));
 
         PackageSetting ps = settings.peekPackageLPr(PACKAGE_NAME_2);
@@ -164,7 +168,7 @@
     public void testEnableDisable() {
         // Write the package files and make sure they're parsed properly the first time
         writeOldFiles();
-        Settings settings = new Settings(getContext(), getContext().getFilesDir());
+        Settings settings = new Settings(getContext(), getContext().getFilesDir(), new Object());
         assertEquals(true, settings.readLPw(null, null, 0, false));
 
         // Enable/Disable a package
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index cfbebba..b265d47 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -506,6 +506,11 @@
     }
 
     @Override
+    public int checkSelfPermission(String permission) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public void enforcePermission(
             String permission, int pid, int uid, String message) {
         throw new UnsupportedOperationException();
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 7531d7b..67a8c2b 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -191,13 +191,13 @@
 
     /** @hide */
     @Override
-    public void grantPermission(String packageName, String permissionName) {
+    public void grantPermission(String packageName, String permissionName, UserHandle user) {
         throw new UnsupportedOperationException();
     }
 
     /** @hide */
     @Override
-    public void revokePermission(String packageName, String permissionName) {
+    public void revokePermission(String packageName, String permissionName, UserHandle user) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/tests/Split/res/values-b+fr+Latn+CA/strings.xml b/tests/Split/res/values-b+fr+Latn+CA/strings.xml
new file mode 100644
index 0000000..108a135
--- /dev/null
+++ b/tests/Split/res/values-b+fr+Latn+CA/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="test">Bonsoir!</string>
+</resources>
diff --git a/tests/Split/res/values-fr-rCA/strings.xml b/tests/Split/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..0837a68
--- /dev/null
+++ b/tests/Split/res/values-fr-rCA/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="test">Bonjour</string>
+</resources>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index 2ad23ed5..bdc1276 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -47,12 +47,12 @@
     public void setAssistStructure(AssistStructure as) {
         mAssistStructure = as;
         mTextRects.clear();
-        final int N = as.getWindowCount();
+        final int N = as.getWindowNodeCount();
         if (N > 0) {
-            AssistStructure.ViewNode window = new AssistStructure.ViewNode();
             for (int i=0; i<N; i++) {
-                as.getWindowAt(i, window);
-                buildTextRects(window, 0, 0);
+                AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i);
+                buildTextRects(windowNode.getRootViewNode(), windowNode.getLeft(),
+                        windowNode.getTop());
             }
         }
         invalidate();
@@ -79,9 +79,8 @@
         if (N > 0) {
             left -= root.getScrollX();
             top -= root.getScrollY();
-            AssistStructure.ViewNode child = new AssistStructure.ViewNode();
             for (int i=0; i<N; i++) {
-                root.getChildAt(i, child);
+                AssistStructure.ViewNode child = root.getChildAt(i);
                 buildTextRects(child, left, top);
             }
         }
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 871e04f..d346731 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -367,33 +367,6 @@
     return currentIndex;
 }
 
-
-String8 AaptLocaleValue::toDirName() const {
-    String8 dirName("");
-    if (language[0]) {
-        dirName += language;
-    } else {
-        return dirName;
-    }
-
-    if (script[0]) {
-        dirName += "-s";
-        dirName += script;
-    }
-
-    if (region[0]) {
-        dirName += "-r";
-        dirName += region;
-    }
-
-    if (variant[0]) {
-        dirName += "-v";
-        dirName += variant;
-    }
-
-    return dirName;
-}
-
 void AaptLocaleValue::initFromResTable(const ResTable_config& config) {
     config.unpackLanguage(language);
     config.unpackRegion(region);
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 7ae5368..4fdc964 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -78,8 +78,6 @@
 
      void writeTo(ResTable_config* out) const;
 
-     String8 toDirName() const;
-
      int compare(const AaptLocaleValue& other) const {
          return memcmp(this, &other, sizeof(AaptLocaleValue));
      }
diff --git a/tools/aapt/tests/AaptConfig_test.cpp b/tools/aapt/tests/AaptConfig_test.cpp
index ef3860c..7618974 100644
--- a/tools/aapt/tests/AaptConfig_test.cpp
+++ b/tools/aapt/tests/AaptConfig_test.cpp
@@ -65,7 +65,7 @@
 TEST(AaptConfigTest, ParseLocales) {
     ConfigDescription config;
     EXPECT_TRUE(TestParse("en-rUS", &config));
-    EXPECT_EQ(String8("en-US"), config.toString());
+    EXPECT_EQ(String8("en-rUS"), config.toString());
 }
 
 TEST(AaptConfigTest, ParseQualifierAddedInApi13) {
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 4acbd1c..80036e5 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -131,11 +131,11 @@
     }
 
     @Override
-    public View createViewFromTag(View parent, String name, AttributeSet attrs,
-            boolean inheritContext) {
+    public View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
+            boolean ignoreThemeAttrs) {
         View view;
         try {
-            view = super.createViewFromTag(parent, name, attrs, inheritContext);
+            view = super.createViewFromTag(parent, name, context, attrs, ignoreThemeAttrs);
         } catch (InflateException e) {
             // try to load the class from using the custom view loader
             try {
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 7a73fae..7f1e977 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -21,9 +21,11 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.util.Xml;
 
 import java.io.IOException;
@@ -36,9 +38,13 @@
  *
  */
 public class LayoutInflater_Delegate {
-
     private static final String TAG_MERGE = "merge";
 
+    private static final String ATTR_LAYOUT = "layout";
+
+    private static final int[] ATTRS_THEME = new int[] {
+            com.android.internal.R.attr.theme };
+
     public static boolean sIsInInclude = false;
 
     /**
@@ -49,7 +55,7 @@
      */
     @LayoutlibDelegate
     /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
-            View parent, final AttributeSet attrs, boolean finishInflate, boolean inheritContext)
+            View parent, Context context, AttributeSet attrs, boolean finishInflate)
             throws XmlPullParserException, IOException {
 
         if (finishInflate == false) {
@@ -61,7 +67,7 @@
 
         // ---- START DEFAULT IMPLEMENTATION.
 
-        thisInflater.rInflate_Original(parser, parent, attrs, finishInflate, inheritContext);
+        thisInflater.rInflate_Original(parser, parent, context, attrs, finishInflate);
 
         // ---- END DEFAULT IMPLEMENTATION.
 
@@ -74,15 +80,50 @@
     }
 
     @LayoutlibDelegate
-    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser, View parent,
-            AttributeSet attrs, boolean inheritContext) throws XmlPullParserException, IOException {
-
+    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser,
+            Context context, View parent, AttributeSet attrs)
+            throws XmlPullParserException, IOException {
         int type;
 
         if (parent instanceof ViewGroup) {
-            final int layout = attrs.getAttributeResourceValue(null, "layout", 0);
+            // Apply a theme wrapper, if requested. This is sort of a weird
+            // edge case, since developers think the <include> overwrites
+            // values in the AttributeSet of the included View. So, if the
+            // included View has a theme attribute, we'll need to ignore it.
+            final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
+            final int themeResId = ta.getResourceId(0, 0);
+            final boolean hasThemeOverride = themeResId != 0;
+            if (hasThemeOverride) {
+                context = new ContextThemeWrapper(context, themeResId);
+            }
+            ta.recycle();
+
+            // If the layout is pointing to a theme attribute, we have to
+            // massage the value to get a resource identifier out of it.
+            int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
             if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, "layout");
+                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
+                if (value == null || value.length() <= 0) {
+                    throw new InflateException("You must specify a layout in the"
+                            + " include tag: <include layout=\"@layout/layoutID\" />");
+                }
+
+                // Attempt to resolve the "?attr/name" string to an identifier.
+                layout = context.getResources().getIdentifier(value.substring(1), null, null);
+            }
+
+            // The layout might be referencing a theme attribute.
+            // ---- START CHANGES
+            if (layout != 0) {
+                final TypedValue tempValue = new TypedValue();
+                if (context.getTheme().resolveAttribute(layout, tempValue, true)) {
+                    layout = tempValue.resourceId;
+                }
+            }
+            // ---- END CHANGES
+
+            if (layout == 0) {
+                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
                 if (value == null) {
                     throw new InflateException("You must specifiy a layout in the"
                             + " include tag: <include layout=\"@layout/layoutID\" />");
@@ -111,13 +152,24 @@
 
                     if (TAG_MERGE.equals(childName)) {
                         // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, childAttrs, false,
-                                inheritContext);
+                        thisInflater.rInflate(childParser, parent, context, childAttrs, false);
                     } else {
                         final View view = thisInflater.createViewFromTag(parent, childName,
-                                childAttrs, inheritContext);
+                                context, childAttrs, hasThemeOverride);
                         final ViewGroup group = (ViewGroup) parent;
 
+                        final TypedArray a = context.obtainStyledAttributes(
+                                attrs, com.android.internal.R.styleable.Include);
+                        final int id = a.getResourceId(
+                                com.android.internal.R.styleable.Include_id, View.NO_ID);
+                        final int visibility = a.getInt(
+                                com.android.internal.R.styleable.Include_visibility, -1);
+                        final boolean hasWidth = a.hasValue(
+                                com.android.internal.R.styleable.Include_layout_width);
+                        final boolean hasHeight = a.hasValue(
+                                com.android.internal.R.styleable.Include_layout_height);
+                        a.recycle();
+
                         // We try to load the layout params set in the <include /> tag. If
                         // they don't exist, we will rely on the layout params set in the
                         // included XML file.
@@ -127,40 +179,27 @@
                         // successfully loaded layout params from the <include /> tag,
                         // false means we need to rely on the included layout params.
                         ViewGroup.LayoutParams params = null;
-                        try {
-                            // ---- START CHANGES
-                            sIsInInclude = true;
-                            // ---- END CHANGES
+                        if (hasWidth && hasHeight) {
+                            try {
+                                // ---- START CHANGES
+                                sIsInInclude = true;
+                                // ---- END CHANGES
 
-                            params = group.generateLayoutParams(attrs);
+                                params = group.generateLayoutParams(attrs);
 
-                        } catch (RuntimeException e) {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(childAttrs);
-                        } finally {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-
-                            if (params != null) {
-                                view.setLayoutParams(params);
+                            } finally {
+                                // ---- START CHANGES
+                                sIsInInclude = false;
+                                // ---- END CHANGES
                             }
                         }
+                        if (params == null) {
+                            params = group.generateLayoutParams(childAttrs);
+                        }
+                        view.setLayoutParams(params);
 
                         // Inflate all children.
-                        thisInflater.rInflate(childParser, view, childAttrs, true, true);
-
-                        // Attempt to override the included layout's android:id with the
-                        // one set on the <include /> tag itself.
-                        TypedArray a = thisInflater.mContext.obtainStyledAttributes(attrs,
-                            com.android.internal.R.styleable.View, 0, 0);
-                        int id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID);
-                        // While we're at it, let's try to override android:visibility.
-                        int visibility = a.getInt(com.android.internal.R.styleable.View_visibility, -1);
-                        a.recycle();
+                        thisInflater.rInflateChildren(childParser, view, childAttrs, true);
 
                         if (id != View.NO_ID) {
                             view.setId(id);
@@ -188,12 +227,6 @@
             throw new InflateException("<include /> can only be used inside of a ViewGroup");
         }
 
-        final int currentDepth = parser.getDepth();
-        while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
-            // Empty
-        }
+        LayoutInflater.consumeChildElements(parser);
     }
-
-
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index e1c58fd..8e74ce1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1010,6 +1010,12 @@
     }
 
     @Override
+    public int checkSelfPermission(String arg0) {
+        // pass
+        return 0;
+    }
+
+    @Override
     public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
         // pass
         return 0;
diff --git a/tools/split-select/Grouper.cpp b/tools/split-select/Grouper.cpp
index 22685cd..55e52fc8 100644
--- a/tools/split-select/Grouper.cpp
+++ b/tools/split-select/Grouper.cpp
@@ -34,7 +34,6 @@
     // Find mutually exclusive splits and group them.
     KeyedVector<SplitDescription, SortedVector<SplitDescription> > densityGroups;
     KeyedVector<SplitDescription, SortedVector<SplitDescription> > abiGroups;
-    KeyedVector<SplitDescription, SortedVector<SplitDescription> > localeGroups;
     const size_t splitCount = splits.size();
     for (size_t i = 0; i < splitCount; i++) {
         const SplitDescription& split = splits[i];
@@ -47,10 +46,6 @@
             SplitDescription key(split);
             key.abi = abi::Variant_none;
             appendValue(abiGroups, key, split);
-        } else if (split.config.locale != 0) {
-            SplitDescription key(split);
-            key.config.clearLocale();
-            appendValue(localeGroups, key, split);
         } else {
             groups.add();
             groups.editTop().add(split);
@@ -67,10 +62,6 @@
         groups.add(abiGroups[i]);
     }
 
-    const size_t localeCount = localeGroups.size();
-    for (size_t i = 0; i < localeCount; i++) {
-        groups.add(localeGroups[i]);
-    }
     return groups;
 }
 
diff --git a/tools/split-select/Grouper_test.cpp b/tools/split-select/Grouper_test.cpp
index a5f9c5a..7294a86 100644
--- a/tools/split-select/Grouper_test.cpp
+++ b/tools/split-select/Grouper_test.cpp
@@ -37,6 +37,8 @@
         addSplit(splits, "en-rUS-sw300dp-xhdpi");
         addSplit(splits, "large");
         addSplit(splits, "pl-rPL");
+        addSplit(splits, "fr-rCA");
+        addSplit(splits, "fr");
         addSplit(splits, "xlarge");
         addSplit(splits, "en-rUS-sw600dp-xhdpi");
         addSplit(splits, "en-rUS-sw300dp-hdpi");
@@ -64,7 +66,7 @@
 };
 
 TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) {
-    EXPECT_EQ(12u, mGroups.size());
+    EXPECT_EQ(15u, mGroups.size());
 }
 
 TEST_F(GrouperTest, shouldGroupDensities) {
@@ -79,7 +81,10 @@
 }
 
 TEST_F(GrouperTest, shouldGroupLocale) {
-    expectHasGroupWithSplits("pl-rPL", "de-rDE");
+    expectHasGroupWithSplits("pl-rPL");
+    expectHasGroupWithSplits("de-rDE");
+    expectHasGroupWithSplits("fr");
+    expectHasGroupWithSplits("fr-rCA");
 }
 
 TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) {